{object}的类型是什么?

Art*_*zuk 8 c++

请考虑以下代码:

void foo (M&) {}

M m;
foo ({m});
Run Code Online (Sandbox Code Playgroud)

因此,表达式{m}被视为rvalue引用,这就是此代码无法编译的原因.

这是真的{object}总是产生临时对象吗?

如果没有,那么如何确定它何时发生?如果是,请考虑以下代码:

struct M {};

struct I {
    I (M&) {}
};

struct MM {
    MM (M& p)
    : m (p), i ( {p} )
    {}

    M& m;
    I i;
};

M m;
MM mm {m};
Run Code Online (Sandbox Code Playgroud)

这里完全没有问题,那么{m}从第一个例子和{p}第二个例子之间的区别是什么?

编译器(GCC 4.8.1)结果(第一个例子):

main.cpp:366:13: error: invalid initialization of non-const reference of type ‘M&’ from an rvalue of type ‘<brace-enclosed initializer list>’
     foo ({m});
             ^
main.cpp:359:6: error: in passing argument 1 of ‘void foo(M&)’
 void foo (M&) {}
Run Code Online (Sandbox Code Playgroud)

Tar*_*ama 2

的类型是什么{object}

这取决于上下文。在某些情况下,例如使用std::initializer_list参数构造类型时,它将是 类型std::initializer_list<decltype(object)>。在其他情况下,它将用于初始化聚合或其他类型的成员,在这种情况下,语法形式本身{object}没有类型。

{object}总是产生临时对象是真的吗?

不,就你的情况而言,不应该。这是C++11 规范中与指定列表初始化的子句顺序相关的错误。旧的措辞意味着您的调用导致构建临时对象(由于非常量引用参数而导致格式错误),但根据新规则,引用绑定到单个初始值设定项列表元素。旧的编译器实现旧的措辞,而新的编译器实现固定的行为。

这里完全没有问题,那么第一个示例中的 {m} 和第二个示例中的 {p} 有什么区别?

不同的是,{m}用于初始化M参数foo(在旧写法下无效),而是{p}初始化I成员。因此,p被视为I构造函数的参数,绑定到M&参数,并且由于p是左值,所以一切都很好。