Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不允许绑定到初始化列表中引用的临时变量超过ctor末尾的理由是什么?_C++ - Fatal编程技术网

C++ 不允许绑定到初始化列表中引用的临时变量超过ctor末尾的理由是什么?

C++ 不允许绑定到初始化列表中引用的临时变量超过ctor末尾的理由是什么?,c++,C++,简单的例子: struct A { A() : i(int()) {} const int& i; }; 来自gcc的错误: 临时绑定到'a::i'只会持续到构造函数退出 12.2p5中的规则: 临时绑定到构造函数中的引用成员 ctor初始值设定项12.6.2持续存在,直到构造函数退出 问题: 有人知道这条规则的理由吗?在我看来,允许临时变量一直存在到引用终止会更好。构造函数初始化列表中的int位于堆栈上 设置该值后,int将超出范围,引用将无效。构造函数初始化列表中的in

简单的例子:

struct A
{
   A() : i(int()) {}
   const int& i;
};
来自gcc的错误:

临时绑定到'a::i'只会持续到构造函数退出

12.2p5中的规则:

临时绑定到构造函数中的引用成员 ctor初始值设定项12.6.2持续存在,直到构造函数退出

问题:


有人知道这条规则的理由吗?在我看来,允许临时变量一直存在到引用终止会更好。

构造函数初始化列表中的int位于堆栈上


设置该值后,int将超出范围,引用将无效。

构造函数初始化列表中的int位于堆栈上

一旦设置了该值,int将超出范围,引用将无效。

我不认为不扩展到对象生命周期需要理由。反之亦然

临时对象的生存期扩展仅扩展到封闭范围,这是自然的,也是有用的。这是因为我们对接收引用变量的生存期有严格的控制。相反,类成员根本不在范围内。想象一下:

int foo();
struct Bar
{
    Bar(int const &, int const &, int const &) : /* bind */ { }
    int & a, & b, & c;
};

Bar * p = new Bar(foo(), foo(), foo());
几乎不可能为foo临时对象定义有意义的生命周期延长

相反,我们有一个默认行为,即foo-temporary的生存期将扩展到包含它的完整表达式的末尾,并且不再扩展。

我认为不扩展到对象生存期不需要理由。反之亦然

临时对象的生存期扩展仅扩展到封闭范围,这是自然的,也是有用的。这是因为我们对接收引用变量的生存期有严格的控制。相反,类成员根本不在范围内。想象一下:

int foo();
struct Bar
{
    Bar(int const &, int const &, int const &) : /* bind */ { }
    int & a, & b, & c;
};

Bar * p = new Bar(foo(), foo(), foo());
几乎不可能为foo临时对象定义有意义的生命周期延长


取而代之的是,我们有一个默认行为,即foo临时表达式的生存期将扩展到包含它的完整表达式的末尾,并且不再扩展。

它将驻留在什么内存中

为了让它按照您建议的方式工作,它不能在堆栈上,因为它必须比任何单个函数调用的寿命更长。它不能放在内存中的结构A之后,因为它无法知道A是如何分配的

充其量只能将其转换为秘密堆分配。然后,当析构函数运行时,需要相应的秘密解除分配。复制构造函数和赋值运算符也需要秘密行为


我不知道是否有人真的考虑过这样做。但就我个人而言,对于一个相当模糊的功能来说,这听起来太复杂了。

它将保存在什么内存中

为了让它按照您建议的方式工作,它不能在堆栈上,因为它必须比任何单个函数调用的寿命更长。它不能放在内存中的结构A之后,因为它无法知道A是如何分配的

充其量只能将其转换为秘密堆分配。然后,当析构函数运行时,需要相应的秘密解除分配。复制构造函数和赋值运算符也需要秘密行为


我不知道是否有人真的考虑过这样做。但就个人而言,对于一个相当模糊的功能来说,这听起来太复杂了。

谢谢,这很有帮助。这与堆栈上的临时对象有关,正如另一个答案所说,这可能是部分原因,但在我看来,这只是一个实现细节。虽然编译器很难跟踪示例中的临时对象。谢谢,这很有帮助。这与堆栈上的临时对象有关,正如另一个答案所说,这可能是部分原因,但在我看来,这只是一个实现细节。虽然编译器很难跟踪示例中的临时对象。理论上,编译器不能简单地在调用方的堆栈帧中创建一个隐藏对象并复制临时覆盖吗?理论上,编译器不能简单地在调用方的堆栈帧中创建一个隐藏对象并复制临时覆盖吗?