如何调用成员初始化列表中引用成员的构造函数?

How to call the constructor of reference members in the member initializer list?

考虑这个例子:

class C {};

class B {
public:
  B(C& c) : c_(c) {};
private:
  C& c_;
};

class A {
public:
  A(C& c) : b(c) {};
private:
  B& b;
};

A 具有 class B 的参考成员 bB 有一个引用 class C 的构造函数。 A 的构造函数引用 class C 并尝试通过使用 c.

调用后者的构造函数来初始化 b

但是 clang 抱怨以下消息:

wtf.cpp:12:13: error: non-const lvalue reference to type 'B' cannot bind to a value of unrelated type 'C'
  A(C& c) : b(c) {};
            ^ ~
1 error generated.

听起来好像 clang 认为我正在将 c 分配给 b,但我的意图是用 c 调用 B 的构造函数。我在这里做错了什么?

您所描述的不限于初始化列表,而是通常的引用构造。以下不应编译:

class C
{};

class B
{
public:
    B(C& c)
    : c_(c)
    {}
private:
    C& c_;
};

int main()
{
    C c;
    B b0(c);  // This works because you actually create an object of type B.

    B& b1(c);  // Error, cannot construct reference to B from C.
    B& b2 = c;  // Same as above, only a different notation.
    // You cannot write a constructor of B to make these lines work,
    // because you do not create an object of type B.
}

class B 的对象可以从对 C 对象的引用构造,但引用不一样。只能从相同类型的对象或继承层次结构中低于类型的对象创建引用。

这正是引用的要点:您不构造对象。您只需为在其他地方创建的对象引入一个新名称。

你不能那样做。引用实际上接近于不可修改的指针。这意味着 B& 只能引用 class BB 的子 class 的对象。并且没有什么比引用的构造更好的了。

您可以从 C 引用构造一个临时 B 对象,但是您不能用临时对象初始化引用,因为一旦引用被初始化,被引用的对象将被摧毁。

所以你必须在 A 中存储一个真实的对象而不是 ref:

    class A {
    public:
      A(C& c) : b(c) {};
    private:
      B b;
    };