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

Popular posts from this blog

java - SNMP4J General Variable Binding Error -

windows - Python Service Installation - "Could not find PythonClass entry" -

Determine if a XmlNode is empty or null in C#? -