With Visual C ++ 2010, I have a class like this:
class MyClass{ public: MyClass(){} MyClass(MyClass &){/*...*/} //A MyClass(const MyClass &){/*...*/} //B template<typename T> MyClass(T &&t){ static_assert( !std::is_same<typename std::remove_cv<typename std::remove_reference<T>::type>::type, MyClass>::value, "Wrapping over wrapping is not allowed!"); } //C }; int main(int, char**){ MyClass a; const MyClass b(a); //assert fail if line A removed auto c=b; //assert fail if line B removed } //If both A and B exists //Warning C4521: multiple copy constructors specified //Furthermore, if both A and B removed //No error or warnings; VC2010 accepts peacefully. //In debug mode you will find the compiler generated trivial copy constructor
According to the C ++ standard, both lines A and B are considered copy constructors, and C is considered a conversion constructor. Not surprisingly, I received a warning that I declared several copy constructors. However, if I delete any of them, static_assert will fail and the code will not compile, which means that the template constructor has gained control.
I am sure that this behavior follows the function overload rule. However, is this a conflict of two rules? If A and B are copy constructors and one of them has been declared, any attempt to copy objects should not depend on the template, is this correct?
Update: According to N3242, 12.8.7,
"The member element template is NEVER INSTALLED to execute a copy of a class object to an object of its class type."
The correct implementation should be:
- No affirmative rejection shall arise if A or B or both are deleted.
- If row B is deleted, building c must fail, because b is a constant.
- If both lines are deleted, the compiler must generate a copy constructor for this class.
- The implementation should warn the user if both lines exist.
Any comments?
source share