6

The Standard in section 12.8/7 says:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. Thus, for the class definition

struct X {
    X(const X&, int);
};

a copy constructor is implicitly-declared. If the user-declared constructor is later defined as

X::X(const X& x, int i =0) { /∗ ... ∗/ }

I can't get the point of that The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. In the example the Standard neither provides a user-declared copy assignment operator nor a destructor. What will happen if we declare a destructor or a copy assignment operator? I've tried to do that as follows:

struct A
{
    ~A(){ };
};

A::A(const A&){ }; //error

int main(){ }

DEMO

but in the example we still have the implicitly-declared copy constructor. What does that rule actual mean?

I thought that if we write the following:

struct A
{
    A(){ };
    A(const A&&){ };
    ~A(){ };
};

A a;

A t = a; //error: call to implicitly-deleted copy constructor of 'A'

int main()
{ 

}

DEMO

the copy-constructor won't explicitly deleted. But thats's not the case.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • 5
    Rule of three. If it's got a user-defined copy assignment operator or a destructor, the default copy constructor probably won't do the right thing, but actually defining it as deleted would be a massive breaking change and wreak havoc with tons of existing code; hence, it's only deprecated. If you have a move special member, then it must be new code, so making it deleted won't break anything. – T.C. Nov 01 '14 at 08:41
  • @T.C. Basically _Deprecated_ means it's not good to use that particular feature, but you can if you eager, does it? –  Nov 01 '14 at 09:01
  • 1
    +1 for making me learn something from standard – Titus Nov 01 '14 at 09:07

2 Answers2

5

This deprecation basically incorporates the Rule of Three (Five). If a user-declared copy assignment operator or destructor is provided, the fact that the copy constructor is defined as defaulted (and not as deleted) is deprecated. That should prevent you from depending upon such an implicitly declared copy constructor in future.

In the example the Standard provides neither copy assignment nor destructor are user-decalred.

The example has nothing to do with the deprecation.

I've tryied to do that as follows: […] but in the example we still have the impliclty-declared copy constructor.

You cannot define an implicitly declared copy constructor - because it's already defined, by = default (no pun intended). You would have to declare it yourself first.

I thought that If we wirte the following: […] the copy-constructor won't explicitly deleted. But it's not true.

You quoted the rule that explicitly specifies that the copy constructor will be implicitly defined as deleted if a move constructor is declared:

If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted;

Clearly,

A(const A&&){ }

Is a move constructor according to [class.copy]/3. If you removed this move constructor then your example compiles, although it uses said deprecated feature.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • But the example from the Standard is ill-formed whatsoever: http://coliru.stacked-crooked.com/a/f88c8ce871b6be9a –  Nov 01 '14 at 09:05
  • That means there is no sense to talk about what will happen if we use the copy-constructor... I think –  Nov 01 '14 at 09:06
  • @DmitryFucintv: Yes, the example is ill-formed, exactly as the standard says immediately after it. The remainder of the sentence, after the fragment you posted, is "then any use of X’s copy constructor is ill-formed because of the ambiguity; no diagnostic is required." – Mike Seymour Nov 01 '14 at 12:25
  • @MikeSeymour I thought the program would be ill-formed if we use the constructor in an expression. "then _any use_ of X’s copy constructor is ill-formed because of the ambiguity; no diagnostic is required." That's if we just declare one, the program won't ill-formed. What's wrong? –  Nov 02 '14 at 07:54
  • @MikeSeymour BTW, as T.C. noted, there is an issue about that http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1344 –  Nov 02 '14 at 08:16
1

Deprecated normally means that something will work, but that it is frowned upon and may not work in the future. I think the standard is saying that if you create a user-declared copy assignment operator or a user-declared destructor it will still create a default copy constructor (if you haven't) - but it may not in the future. So they want you to create your own copy constructor now, if you have one of the other two, and in the future they may force you to.

Scooter
  • 6,802
  • 8
  • 41
  • 64