初始值设定项列表和 const - 这是合法C++

Initializer list and const& - is this legal C++

本文关键字:C++ const 列表      更新时间:2023-10-16

考虑:

#include <iostream>
#include <vector>
class A
{
public:
    const int& i;    
};
class B
{
public:
    const std::vector<int>& i;
};
int main()
{
    A a = { 3 };
    std::cout << a.i << std::endl;
    B b = { { 1, 2 } };
    std::cout << b.i[0] << " " << b.i[1] << std::endl;
}

VS2015更新3上,由于向量b.i为空,因此在运行时最后一行崩溃;在gcc(4.9.2)上,运行正常并显示预期的输出(3 1 2)。所以在 VS 上,它对 int "有效"(做我期望的),但不是向量。

这是一个VS错误还是只是在gcc上运行的意外?

第一个是确定的,当分配给引用时,临时的生存期会延长。其次是UB AFAIK,因为{ { 1, 2 } }std::initializer_list<>,而不是直接std::vector<>。延长生存期临时对象不是传递的(即,它持续到当前函数结束,在本例中为构造函数),只有本地对象会延长。

它意外地在 gcc 上工作,因为这绝对是未定义的行为。

为了满足B的初始化,编译器需要构造一个临时vector<int>。由于对该向量的引用是const的,编译器认为使用它来初始化B没有问题。但是,一旦初始化结束,临时对象就会变得无效,因此在初始化之外通过引用访问它是未定义的行为。