初始化列表和const& - 这是合法的C ++

时间:2016-07-15 14:11:27

标签: c++

考虑:

#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?

2 个答案:

答案 0 :(得分:1)

第一个是好的,临时的生命周期在分配给参考时会延长。其次是UB AFAIK,因为{ { 1, 2 } }std::initializer_list<>,而不是std::vector<>。延长生命周期临时对象是不可传递的(即,它持续到当前函数的结尾,在这种情况下,构造函数),只有本地的临时对象会延长。

答案 1 :(得分:1)

它偶然适用于gcc,因为这肯定是未定义的行为。

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