Is there a difference in C++ between copy initialization and direct initialization? -
suppose have function:
void my_test() { a1 = a_factory_func(); a2(a_factory_func()); double b1 = 0.5; double b2(0.5); c1; c2 = a(); c3(a()); }
in each grouping, these statements identical? or there (possibly optimizable) copy in of initializations?
i have seen people both things. please cite text proof. add other cases please.
a a1 = a_factory_func(); a2(a_factory_func());
depends on type a_factory_func()
returns. assume returns a
- it's doing same - except when copy constructor explicit, first 1 fail. read 8.6/14
double b1 = 0.5; double b2(0.5);
this doing same because it's built-in type (this means not class type here). read 8.6/14.
a c1; c2 = a(); c3(a());
this not doing same. first default-initializes if a
non-pod, , doesn't initialization pod (read 8.6/9). second copy initializes: value-initializes temporary , copies value c2
(read 5.2.3/2 , 8.6/14). of course require non-explicit copy constructor (read 8.6/14 , 12.3.1/3 , 13.3.1.3/1 ). third creates function declaration function c3
returns a
, takes function pointer function returning a
(read 8.2).
delving initializations direct , copy initialization
while identical , supposed same, these 2 forms remarkably different in cases. 2 forms of initialization direct , copy initialization:
t t(x); t t = x;
there behavior can attribute each of them:
- direct initialization behaves function call overloaded function: functions, in case, constructors of
t
(includingexplicit
ones), , argumentx
. overload resolution find best matching constructor, , when needed implicit conversion required. - copy initialization constructs implicit conversion sequence: tries convert
x
object of typet
. (it may copy on object to-initialized object, copy constructor needed - not important below)
as see, copy initialization in way part of direct initialization regard possible implicit conversions: while direct initialization has constructors available call, , in addition can implicit conversion needs match argument types, copy initialization can set 1 implicit conversion sequence.
i tried hard , got following code output different text each of forms, without using "obvious" through explicit
constructors.
#include <iostream> struct b; struct { operator b(); }; struct b { b() { } b(a const&) { std::cout << "<direct> "; } }; a::operator b() { std::cout << "<copy> "; return b(); } int main() { a; b b1(a); // 1) b b2 = a; // 2) } // output: <direct> <copy>
how work, , why output result?
direct initialization
it first doesn't know conversion. try call constructor. in case, following constructor available , exact match:
b(a const&)
there no conversion, less user defined conversion, needed call constructor (note no const qualification conversion happens here either). , direct initialization call it.
copy initialization
as said above, copy initialization construct conversion sequence when
a
has not typeb
or derived (which case here). ways conversion, , find following candidatesb(a const&) operator b(a&);
notice how rewrote conversion function: parameter type reflects type of
this
pointer, in non-const member function non-const. now, call these candidatesx
argument. winner conversion function: because if have 2 candidate functions both accepting reference same type, less const version wins (this is, way, mechanism prefers non-const member function calls non-const objects).note if change conversion function const member function, conversion ambiguous (because both have parameter type of
a const&
then): comeau compiler rejects properly, gcc accepts in non-pedantic mode. switching-pedantic
makes output proper ambiguity warning too, though.
i hope helps make clearer how these 2 forms differ!
Comments
Post a Comment