{对象}的类型是什么

What is the type of {object}?

本文关键字:类型 是什么 对象      更新时间:2023-10-16

考虑以下代码:

void foo (M&) {}
M m;
foo ({m});

因此,表达式 {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};

这里根本没有问题,那么第一个示例的{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&) {}

{object}的类型是什么?

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

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

不,就您而言,不应该。这是与指定列表初始化的子句的排序相关的C 11规格中的一个错误。旧的措辞意味着您的呼叫导致临时构建(由于非const参考参数而形成不正确),但是根据新规则,该引用绑定到单个初始化器列表元素。您的旧编译器实现了旧措辞,而新的编译器实施了固定的行为。

这里根本没有问题,那么第一个示例中{m}和第二个{p}之间有什么区别?

区别在于,{m}用于初始化fooM参数(旧措辞下),但{p}初始化了I成员。因此,p被视为I构造函数的参数,与M&参数结合,并且由于p是一个LVALUE,因此一切都很好,而且很花哨。

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

否(请继续)。

两个片段都是有效的(您应该使用最新的编译器)并将成功编译。

{p}案例属于[over.match.list]/p1

当非聚集类T型类Type Typer typer-Initializatizatizationalizatization Intializatizatized Intializatization Intializatization Intialization Intialized,以指定根据本节中规则执行过载分辨率时,Overload分辨率在两个阶段中选择构造函数:

(1.1) 最初,候选函数是T类的初始化列表构造函数([dcl.init.list]),参数列表由单个参数组成。

(1.2) 如果找不到可行的初始列表构造函数,则再次执行过载分辨率,其中候选功能是T类的所有构造函数,而参数列表由初始器列表的元素组成。

特别是在(1.2)中,而{m}是另一种情况的列表初始化。