Multiple Copy Designers Indicated

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?

+4
source share
2 answers

First of all, template<T> should be template <typename T> .

I use gcc 4.4.3 on 64-bit Ubuntu Linux, the codes behave differently than you showed in the post.

  • If nothing has changed, the codes may be compiled without warning. Constructor A and B are called one after another.
  • If I comment out line A, it cannot be compiled the same way you said: line failure const MyClass b(a); . The reason is that object a is not constant, so constructor B cannot be matched, and the compiler must create an instance of the template constructor. Of course, const MyClass and MyClass are different types.
  • However, if I comment only on line B, the codes can be compiled successfully and the template copy constructor is called. Object b is a persistent object, so construct A cannot be matched, and the compiler instantiates the template constructor. However, the question remains: should static_assert fail or not? The difference may be due to the difference of the platform / compiler. It seems that GCC implements is_same<MyClass&&, MyClass>::value to be true. You can use typeid to print both types.
+1
source

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?

A constructor that is not a copy constructor can still be used to copy objects. In your case, the constructor created from the constructor template is used to copy the object. What well.

0
source

All Articles