constructor - c++ copy initialization & direct initialization, the weird case -
before continue reading this, please read is there difference in c++ between copy initialization , direct initialization? first, make sure understand talking about.
i'll summarize rule here first (read standard n3225 8.5/16, 13.3.1.3, 13.3.1.4, , 13.3.1.5),
1) direct initialization, constructors considered overloading set, overloading resolution select best 1 according overloading resolution rules.
2) copy initialization , source type same destination type or derived destination type, rule same above except converting constructors (constructors without explicit) considered overloading set. means explicit copy/move constructors not considered overloading set.
3) copy initialization cases not included in (2) above (source type different destination type , not derived destination type), first consider user-defined conversion sequences can convert source type destination type or (when conversion function used) derived class thereof. if conversion succeeds, result used direct initialize destination object.
3.1) during user-defined conversion sequence, both converting ctors (non-explicit ctors) , non-explicit conversion functions considered, according rules in 8.5/16 , 13.3.1.4.
3.2) result prvalue direct initialize destination object, rules listed in (1), see 8.5/16.
okay, enough rules, let's @ weird code, have no idea on reasoning wrong, or compilers wrong. please me, thanks.
struct { (int) { } a() { } explicit a(const a&) { } }; struct b { operator a() { return 2; } //1) visual c++ , clang passes //gcc 4.4.3 denies this, says no viable constructor available }; int main() { b b; a = b; //2) oops, compilers deny }
in understanding, (1),
operator a() { return 2; }
because c++ has rule function return taken copy-initialization, according rule above, 2 firstly implicitly converted a, should ok because has constructor a(int). converted temporary prvalue used direct-initialize returned object, should ok because direct-initialization can make use of explicit copy constructor. gcc wrong.
for (2),
a = b;
in understanding, firstly b implicitly converted a, operator a(), , converted value shall used direct-initialize a, can of course call explicit copy constructor? should pass compilation , compilers wrong?
note (2), both visual c++ , clang has error similar to, "error, cannot convert b a", if remove explicit keyword in copy constructor of a, error gone..
thanks reading.
edit 1
because still didn't meant, quote following standard 8.5/16,
otherwise (i.e., remaining copy-initialization cases), user-defined conversion sequences can convert source type destination type or (when conversion function used) derived class thereof enumerated described in 13.3.1.4, , best 1 chosen through overload resolution (13.3). if conversion cannot done or ambiguous, initialization ill-formed. function selected called initializer expression argument; if function constructor, call initializes temporary of cv-unqualified version of destination type. temporary prvalue. result of call (which temporary constructor case) used direct-initialize, according rules above, object destination of copy-initialization. in cases, implementation permitted eliminate copying inherent in direct-initialization constructing intermediate result directly object being initialized; see 12.2, 12.8.
note did mention direct initialize after user-defined conversion. means, in understanding, following code shall obey rules commented, confirmed both clang, coomeau online, visual c++, gcc 4.4.3 fails both (1) , (2). although weird rule, follows reasoning standard.
struct { (int) { } a() { } explicit a(const a&) { } }; int main() { a = 2; //1)ok, first convert, direct-initialize a = (a)2; //2)oops, constructor explicit, not viable here! }
you declared copy constructor explicit
(btw, why?), means can no longer used implicit copying of class objects. in order use constructor copying forced use direct-initialization syntax. see 12.3.1/2
2 explicit constructor constructs objects non-explicit constructors, direct-initialization syntax (8.5) or casts (5.2.9, 5.4) explicitly used.
the issue can illustrated following shorter example
struct { a() {} explicit a(const a&) {} }; int main() { a; b = a; // error: copy-initialization c(a); // ok: direct-initialization }
this blocks of conversions working, since of them rely on copy-initialization, in turns relies on implicit copying. , disabled implicit copying.
additionally, see defect report #152 covers specific issue. although i'm not sure consequences of "proposed resolution" supposed be...
Comments
Post a Comment