初始化不可复制且不可移动类型的成员

Oba*_*bay 0 c++

给定一个不可复制/可移动的 struct U,该结构的成员不能在构造函数中分配(请参阅C)。它们只能通过成员初始值设定项列表来初始化(请参阅 参考资料S)。

struct U {
    U(int x);
    U(U &other) = delete;
    U(U &&other) = delete;
};

struct S {
    S(int x) : u(x) {}
    U u;
};

struct C {
    C(int x) { u = U(x); }  // compiler complains: cannot assign
    U u;
};
Run Code Online (Sandbox Code Playgroud)

错误:

<source>:13:5: error: constructor for 'C' must explicitly initialize the member 'u' which does not have a default constructor
    C(int x) { u = U(x); }
    ^
<source>:14:7: note: member is declared here
    U u;
      ^
<source>:1:8: note: 'U' declared here
struct U {
       ^
<source>:13:18: error: object of type 'U' cannot be assigned because its copy assignment operator is implicitly deleted
    C(int x) { u = U(x); }
                 ^
<source>:4:5: note: copy assignment operator is implicitly deleted because 'U' has a user-declared move constructor
    U(U &&other) = delete;
    ^
Run Code Online (Sandbox Code Playgroud)

代码在这里: https: //godbolt.org/z/11nvh1ze4

编译器当然有理由抱怨。如果x在构造函数主体中进行计算,则不能使用初始值设定项列表。是否有任何语法可以允许这样做?

for*_*818 6

您无法在构造函数主体中初始化它。成员在构造函数主体执行之前初始化。如果x在调用构造函数时计算 ,那么您仍然可以使用成员初始值设定项列表。例如,当您void f(int&)需要调用 来检索 的参数时u

struct C {
    C(int x) : u(compute_x(x)) { } 
    U u;
private:
    static int compute_x(int x) { f(x); return x; }
};
Run Code Online (Sandbox Code Playgroud)

还有另一个现已删除的答案提出了关于构造函数的心智模型的一个很好的观点。这里要注意的一点是构造函数主体不是用于成员的初始化。这发生在身体运行之前。一旦掌握了窍门,您会发现自己编写了许多构造函数,其主体只不过是{},因为构造函数除了设置类成员之外实际上并不常见。

  • @Obay哦,对了,然后将`f`包装到`compute_x`中:`static int ompute_x(int x) { f(x); 返回x;}` (3认同)