class L {
public:
L(const std::string& name, std::initializer_list<long long int> dims, float* data);
std::string name;
std::initializer_list<long long int> dims;
float* data;
};
我可以关注
vector<L> input = {
{"aaaaa", {1, 20, 1400, 1}, input_data}};
但是我不能跟随它(它编译,但运行会崩溃)
long long int a =20;
vector<L> input = {
{"aaaaa", {1, a, 1400, 1}, input_data}};
答案 0 :(得分:2)
std::initializer_list
不是容器。它是对临时数组的引用。它是目的用于初始化另一个对象的类型(因此称为初始化程序 _list),并且不应将其用于除之外的任何 这一点。
initializer_list
引用的临时数组与C ++中的任何其他临时数组一样。在
vector<L> input = {
{"aaaaa", {1, 20, 1400, 1}, input_data}};
执行此语句后,临时数组将立即销毁。因此,您将存储指向已销毁数组的指针。因此,您的计划有UB。
现在,如果使用变量,为什么你的UB只会导致崩溃?
那是因为“临时数组”意味着编译器想要的意思。在{1, 20, 1400, 1}
的情况下,这些都是文字。因此,编译器可以将该数组放在二进制文件中的静态存储中,而不是在运行时将其作为堆栈数组。这节省了运行时堆栈空间,因此可以认为是合理的优化。
但是,一旦在braced-init-list中使用变量,就无法工作(除非它是constexpr
变量)。因此编译器需要更严格地遵循临时措辞。因此,它创建一个堆栈数组,在该代码执行后回收。因此,当您稍后访问它时......繁荣。
即便如此,也不依赖于此。你的程序有UB。