Re: On the path to move constructors: compile error.
* Andy Venikov:
Some time has passed since my previous post and I still don't know the
answer.
Can somebody explain why do I still need a "normal" copy-constructor
when passing an object by const-reference?
Here's my original post:
Andrew Venikov wrote:
On most compilers the following will not compile:
struct A
{
A() {}
A(A &) {} //Note: no const
};
void Func(A const &);
.....
Func(A()); //Compile-time error here in gcc prior to 4.3 and Comeau
The error that gcc emits is:
error: no matching function for call to 'A::A(A)'
test.cpp:11: note: candidates are: A::A(A&)
The error that Comeau emits is:
"ComeauTest.c", line 20: error: "A::A(A &)", required for copy that
was eliminated,
is not callable because reference parameter cannot be bound
to rvalue
Func(A());
But if I use gcc 4.3, or enable c++0x extensions in Comeau, then this
compiles without
any errors.
I've seen this behavior referenced in several places
(Alexandrescu's MOJO article: http://www.ddj.com/database/184403855)
(Dave Abraham's clarification:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html)
Also, I've encountered it myself a couple of times (especially when
dealing with auto_ptr, since
it doesn't have a copy-constructor that takes a const reference).
My question is why? I couldn't find any plausible reference that
mandates this behavior.
In the current standard's ?8.5.3/5,
-- If the initializer expression is an rvalue, with T2 a class type,
and "cv1 T1" is reference-compatible with "cv2 T2", the reference
is bound in one of the following ways (the choice is implementation-
defined):
-- The reference is bound to the object represented by the rvalue
(see 3.10) or to a sub-object within that object.
-- A temporary of type "cv1 T2" [sic] is created, and a constructor
is called to copy the entire rvalue object into the temporary.
The reference is bound to the temporary or to a sub-object within
the temporary.
The constructor that would be used to make the copy shall be callable
whether or not the copy is actually done.
This language is removed/changed in the C++0x draft, so that the binding is
direct when that's possible, in which case having an accessible copy constructor
is not required.
The C++0x change influences e.g. passing of a std::auto_ptr rvalue.
The intuition tells me that if a function takes something by a const
reference, then there
should be no copy-constructors invoked.
Dave Abrahams' article that I mentioned talks about a specific clause
in the standard: 8.5.3/5.
But reading that clause I couldn't infer anything that would suggest
the mentioned behavior.
See above.
Cheers & hth.,
- Alf
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]