给出以下结构:
struct A {
template<typename T, std::size_t N>
A(T const(&array)[N]) {}
template<typename T, std::size_t N>
A& operator=(T const(&array)[N]) { return *this; }
};
代码:
// a is of type A
a = {1, 2, 3, 4};
编译得很好,因为std::initialiser_list
被隐式转换为数组引用。
但是
A a {1, 2, 3, 4};
A a = {1, 2, 3, 4};
无法同时使用Clang和GCC进行编译。当我添加接受std::initialiser_list<T>
的构造函数时,它确实会编译。
我想念什么?
答案 0 :(得分:2)
您只需要多余的括号或括号即可。
A a{{1, 2, 3, 4}}; // ok
A b({1, 2, 3, 4}); // ok
这样做的原因是外部大括号/括号用于A
,内部大括号用于列表初始化的array
对象。
有了赋值,您就不需要多余的括号或花括号,因为它们仅在函数调用中隐含了:
a = {1, 2, 3, 4};
等效于:
a.operator=({1, 2, 3, 4});
或多或少。
当我添加一个接受
std::initialiser_list<T>
的构造函数时,它确实会编译。
详细说明列表初始化的工作方式。当您编写A a{1, 2, 3, 4}
时,我们首先要寻找某个std::initializer_list<T>
构造函数(我们还没有找到,所以找不到它)的 ,然后寻找我们可以使用四个参数(不存在)调用的构造函数。添加额外的()
或{}
意味着我们正在寻找可以用 one 自变量调用的构造函数,并用1, 2 ,3, 4
进行初始化。>
一旦添加了std::initializer_list<T>
构造函数,现在这对于初始化的第一阶段是可行的选择。
请注意,
编译得很好,因为
std::initialiser_list
被隐式转换为数组引用。
不正确。这个问题的任何地方都没有std::initializer_list
。 {1, 2, 3, 4}
在C ++中很有趣。它没有类型或任何东西。这只是一个 braised-init-list 。它仅基于上下文赋予我们含义。在这种情况下,不是将事物转换为其他事物……它只是数组的初始化程序的集合。