class AAA {
public:
AAA() {}
AAA(const AAA&) {}
};
class BBB {
public:
BBB() {}
operator AAA() { AAA a; return a; }
};
int main() {
BBB b;
AAA a = {b};
}
The above code compiles on g++ and vc++, but not clang++.
The traditional syntax AAA a = b;
compiles ok on all three.
class AAA {};
class BBB {
public:
BBB() {}
operator AAA() { AAA a; return a; }
};
int main() {
BBB b;
AAA a = {b};
}
The above code doesn't compile on any of g++, vc++, clang++. The only difference against the first code snippet is that I removed the two user-provided constructors of AAA.
Again, the traditional syntax AAA a = b;
compiles ok on all three.
I'm quite sure that the traditional syntax of copy-initialization is well-defined in the case of an initializer with a conversion operator. But for the C++11 copy-list-initialization, I'm confused. Is clang taking the correct action rejecting the initialization or g++/vc++ taking the correct action accepting the initialization (as seen in the first code snippet)? And why such a trivial change as done in the second code snippet will result in that significant different behavior? What's the difference between copy-list-initialization and traditional copy-initialization in this case after all?
EDIT: Adding a third case:
class CCC {};
class AAA {
public:
AAA() {}
AAA(const AAA&) {}
AAA(const CCC&) {}
};
class BBB {
public:
BBB() {}
operator CCC() {CCC c; return c;}
};
int main() {
BBB b;
AAA a = {b};
}
The above code compiles for all three compilers. The conversion operator works if the final destination constructor is not the copy constructor?
In this case, the traditional syntax AAA a = b;
fails to compile for all three as expected, since traditional copy-initialization allows one level of user-defined implicit conversion at most before arriving at the final copy constructor (the final destination can only be the copy constructor).
Begging for a systematic explanation for all these mess...
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…