By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,492 Members | 1,264 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,492 IT Pros & Developers. It's quick & easy.

Problems when giving default value for 'const auto_ptr &' argument

P: n/a
Consider the following working code:

#include <memory>
#include <iostream>

void print_ptr( const std::auto_ptr< int > & thePtr =
std::auto_ptr< int >() )
{
std::cout << "Ptr address: " << thePtr.get() << std::endl;
}

int main()
{
std::auto_ptr< int > somePtr( new int );
print_ptr( somePtr );
print_ptr();
return 0;
}


Using GCC 3.3.4 it compiles without warning.

Using GCC 4.0.2 it gives the following errors:

foo.cpp: In function ‘int main()’:
foo.cpp:15: error: no matching function for call to
‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>)’
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:349: note: candidates are:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp >) [with _Tp = int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:212: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = int, _Tp
= int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:199: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = int]
foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
std::auto_ptr<int>&)’

It appears that having a default value of 'std::auto_ptr<T>()' to
a parameter of type 'const std::auto_ptr<T> &' is not allowed in
GCC 4.0.2. Is there something in the C++ standard that is enforced in
4.0.2 and not in 3.3.4, or is it purely compiler-specific.

Does it have anything to do with the parameter being a reference?
--
Mvh / Regards
Rein Anders Apeland
MIVU Solutions

Sep 14 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Wed, 14 Sep 2005 13:56:13 +0200, Rein Anders Apeland
<ap*****@mivu.no> wrote:
Consider the following working code:

#include <memory>
#include <iostream>

void print_ptr( const std::auto_ptr< int > & thePtr =
std::auto_ptr< int >() )
{ [...] print_ptr();
return 0;
}

Using GCC 3.3.4 it compiles without warning.

Using GCC 4.0.2 it gives the following errors:

foo.cpp: In function ‘int main()’:
foo.cpp:15: error: no matching function for call to
‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>) ’
I'm assuming line 15 is "print_ptr();".
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:349: note: candidates are:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_T p>) [with _Tp = int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:212: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>& ) [with _Tp1 = int, _Tp
= int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:199: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp> &) [with _Tp = int]
foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
std::auto_ptr<int>&)’

It appears that having a default value of 'std::auto_ptr<T>()' to
a parameter of type 'const std::auto_ptr<T> &' is not allowed in
GCC 4.0.2. Is there something in the C++ standard that is enforced in
4.0.2 and not in 3.3.4, or is it purely compiler-specific.
I'm reading an old standard, but it certainly allows temporaries to be
bound to references (section 12.2.5). I couldn't think of/find any
restrictions on using temporaries which would apply in this case. I
expect the responsibility lies with GCC 4.0.2.
Does it have anything to do with the parameter being a reference?


Based on the error message, no. It has to do with GCC not using
pass-by-reference semantics for the temporary when invoking
std::auto_ptr's (copy) constructor even though GCC could. As to why
GCC 4.0.2 is trying to pass the temporary to the constructor rather
than binding the reference to the temporary (as 3.3.4 does), I don't
know. Perhaps if GCC 4.0.2 would bind the temporary to a reference it
wouldn't be trying to invoke the constructor with the temporary during
thePtr's initialization.

If you're ever curious about a question of the form "Does it have
anything to do with x being y?", try changing x to something related
to y.
Sep 15 '05 #2

P: n/a
On Wed, 2005-09-14 at 18:36 -0700, Kanenas wrote:
On Wed, 14 Sep 2005 13:56:13 +0200, Rein Anders Apeland
<ap*****@mivu.no> wrote:
Consider the following working code:

#include <memory>
#include <iostream>

void print_ptr( const std::auto_ptr< int > & thePtr =
std::auto_ptr< int >() )
{ [...]
print_ptr();
return 0;
}

Using GCC 3.3.4 it compiles without warning.

Using GCC 4.0.2 it gives the following errors:

foo.cpp: In function ‘int main()’:
foo.cpp:15: error: no matching function for call to
‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>) ’


I'm assuming line 15 is "print_ptr();".
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:349: note: candidates are:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_T p>) [with _Tp = int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:212: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>& ) [with _Tp1 = int, _Tp
= int]
/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
++/4.0.2/memory:199: note:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp> &) [with _Tp = int]
foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
std::auto_ptr<int>&)’

It appears that having a default value of 'std::auto_ptr<T>()' to
a parameter of type 'const std::auto_ptr<T> &' is not allowed in
GCC 4.0.2. Is there something in the C++ standard that is enforced in
4.0.2 and not in 3.3.4, or is it purely compiler-specific.

I'm reading an old standard, but it certainly allows temporaries to be
bound to references (section 12.2.5). I couldn't think of/find any
restrictions on using temporaries which would apply in this case. I
expect the responsibility lies with GCC 4.0.2.
Does it have anything to do with the parameter being a reference?


Based on the error message, no. It has to do with GCC not using
pass-by-reference semantics for the temporary when invoking
std::auto_ptr's (copy) constructor even though GCC could. As to why
GCC 4.0.2 is trying to pass the temporary to the constructor rather
than binding the reference to the temporary (as 3.3.4 does), I don't
know. Perhaps if GCC 4.0.2 would bind the temporary to a reference it
wouldn't be trying to invoke the constructor with the temporary during
thePtr's initialization.


In GCC 4.0.2, passing a temporary std::string() to a parameter of
type 'const std::string &' works fine. What could be the difference
between std::string and std::auto_ptr that triggers the error message?


If you're ever curious about a question of the form "Does it have
anything to do with x being y?", try changing x to something related
to y.

--
Mvh / Regards
Rein Anders Apeland
MIVU Solutions

Sep 15 '05 #3

P: n/a
> As to why
GCC 4.0.2 is trying to pass the temporary to the constructor rather
than binding the reference to the temporary (as 3.3.4 does), I don't
know.


When initialising a const reference to an rvalue (which we are in this
case), the compiler may either:

a) Bind the reference directly to the object that the rvalue
represents, or
b) Construct a temporary const object from the rvalue, and bind the
reference to the temporary.

The choice is implementation-defined, but the standard says that the
constructor that would be used in (b) must be available anyway.
However for auto_ptr, such a constructor is *not* available, because
auto_ptr's copy constructor takes a non-const reference (to which an
rvalue cannot be bound). So the new error is correct. See section
8.5.3.5 of the Standard for gory details.

Incidentally, the Microsoft implementation I'm currently looking at
(incorrectly) provides an auto_ptr which takes a const reference.
Plenty of code has been written that relies on this, sadly.

The difference with std::string (as questioned elsewhere on this
thread), is that std::string *does* provide a copy constructor from a
const reference - so (a) and (b) above are satisfied.

Sep 15 '05 #4

P: n/a
On Thu, 2005-09-15 at 07:15 -0700, Pete C wrote:
As to why
GCC 4.0.2 is trying to pass the temporary to the constructor rather
than binding the reference to the temporary (as 3.3.4 does), I don't
know.
When initialising a const reference to an rvalue (which we are in this
case), the compiler may either:

a) Bind the reference directly to the object that the rvalue
represents, or
b) Construct a temporary const object from the rvalue, and bind the
reference to the temporary.

The choice is implementation-defined, but the standard says that the
constructor that would be used in (b) must be available anyway.
However for auto_ptr, such a constructor is *not* available, because
auto_ptr's copy constructor takes a non-const reference (to which an
rvalue cannot be bound). So the new error is correct. See section
8.5.3.5 of the Standard for gory details.

Incidentally, the Microsoft implementation I'm currently looking at
(incorrectly) provides an auto_ptr which takes a const reference.
Plenty of code has been written that relies on this, sadly.

The difference with std::string (as questioned elsewhere on this
thread), is that std::string *does* provide a copy constructor from a
const reference - so (a) and (b) above are satisfied.


Thanks a lot! I now see why GCC 4.0.2 acts the way it does, and why
it must be that way.

--
Mvh / Regards
Rein Anders Apeland
MIVU Solutions

Sep 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.