恒定参考数据成员

时间:2018-11-24 08:22:23

标签: c++ c++11

假设我们有一个带有恒定引用数据成员的结构。

struct A {
    A() : i{5} {}
    const int& foo() const { return i; }
    const int& i;
};

您知道为什么整数5的输出不同吗?

A a{};
std::cout << a.i << std::endl;
std::cout << a.foo() << std::endl;

5
-858993460

2 个答案:

答案 0 :(得分:3)

代码格式错误。您正在从文字i初始化5,这需要构造一个临时对象,然后将其绑定到i。临时变量将在构造函数退出时销毁,然后i悬挂起来,之后对其进行的任何取消引用都将导致UB,这意味着一切皆有可能。

根据标准,[class.base.init]/8

  

绑定到引用成员中的临时表达式   mem初始化程序格式错误。 [示例:

struct A {
  A() : v(42) { }   // error
  const int& v;
};
     

-示例]

BTW:由于标准声明其为格式错误,因此要求编译器为其发布诊断信息。 gcc(给出警告)和clang(给出错误)的行为都符合;如果VS2017没有发出任何诊断,则表明它不符合标准。

答案 1 :(得分:0)

使用constant值而不是literal

这是自Class::Class() : member{arg1, arg2, ...} {...起的c++11个直接列表初始化。

尝试一下:

 struct A {
    const int t = 5;
    A() : i{ t } { }
    const int& foo() const { return i; }
    const int& i;
};

int main()
{
    A a{};
    std::cout << a.i << std::endl;
    std::cout << a.foo() << std::endl;

    return 0;
}