简体   繁体   中英

Aggregate initialization of class with noncopyable member

Suppose I have some class with deleted copy constructor:

struct NoCopy
{
    NoCopy(int) {}
    NoCopy(const NoCopy &) = delete;
};

I use this class in another class:

struct Aggregate
{
    NoCopy nc;
};

But when I'm trying to use aggregate initialization

int main()
{
    Aggregate a{3};
}

Compiler outputs the following error:

error: use of deleted function ‘NoCopy::NoCopy(const NoCopy&)’

Why does aggregate initialization requires copy constructors of class's members? Does aggregate initialization initialize all members using copy constructors?

The correct syntax for what you want is:

Aggregate a{{3}};

This provides an initializer for the NoCopy member. Without the extra {} the compiler needs to perform a conversion from int to NoCopy (which it happily does via the non-explicit constructor), and then use that to construct nc . This would normally occur as a move construction but by deleting the copy ctor you have effictively deleted the move constructor as well.

An easier way to think about it might be to imagine NoCopy had a value constructor taking two arguments instead of one:

struct NoCopy {
    NoCopy(int, int);
};

Now if you wrote

Aggregate a{1, 2};

that would indicate that 1 is used to initialize nc and 2 is used to initialize something else (compile-time error). You'd have to add the extra {} for this to make sense

Aggregate a{{1, 2}};

A third way involves looking at a function call:

struct NoCopy {
  NoCopy(int) {}
  NoCopy(const NoCopy &) = delete;
};

void fun(NoCopy) { }

int main() {
  fun(1); // wrong
  fun({1}); // right
}

In the // wrong version, a temporary NoCopy object is constructed at the callsite using the NoCopy(int) constructor. Then that temporary is passed by value into fun , but since NoCopy isn't copyable, it fails.

In the // right version you are providing the initializer list for the argument to be constructed with. No copies are made.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM