运算符“=”不匹配(std::array<T, 3> 和 std::initializer_list<T>)
no match for operator '=' (std::array<T, 3> and std::initializer_list<T>)
我有一个模板 vec<T>
class 用于长度等于 3 的数学向量。
它看起来像这样:
template <typename T>
class vec{
public:
vec() { /**/ }
vec(std::initializer_list<T> list) { /**/ }
private:
std::array<T, 3> data;
};
我知道,可以这样用 std::initializer_list
初始化 std::array
:
std::array<int, 3> a = {1, 2, 3};
所以我想要一个带有 std::initializer_list
的构造函数来初始化我的向量,如下所示:
vec<int> v = {1, 2, 3};
我也有一个解决方案:只需遍历 std::initializer_list
个元素并写入 data
:
vec(std::initializer_list<T> list) {
size_t i = 0;
for (auto it = list.begin(); it != list.end(); it++) {
data[i++] = *it;
}
}
我试图让构造函数看起来像这样(因为 std::array
有一个带有 std::initializer_list
的构造函数):
vec(std::initializer_list<T> list) {
data = list;
}
但是当我尝试编译程序时,出现错误:
no match for ‘operator=’ (operand types are ‘std::array<int, 3>’ and ‘std::initializer_list<int>)’
这里有什么问题?为什么我不能以这种方式使用初始化列表初始化 std::array
?
作为一种可能的 work-around,您可以添加一个采用 std::array
的构造函数重载,并使用构造函数初始化列表(不要与 std::initializer_list
混淆)来初始化 data
:
vec(std::array<T, 3> const& list)
: data{ list }
{
}
Why can't I initialize std::array
with initializer list in such a way?
Braced-init-list 和 std::initializer_list
are not the same thing. (Even std::initializer_list
could be constructed from braced-init-list.) std::array
is an aggregate and could be aggregate-initialized 或由 braced-init-list 分配为
std::array<int, 3> a = {1, 2, 3};
a = {4, 5, 6}; // convert {4, 5, 6} to std::array then assign to a
请注意 {1, 2, 3}
和 {4, 5, 6}
都是 braced-init-list 而不是 std::initializer_list
。
std::array
无法从 std::initializer_list
初始化(或分配);它的构造函数和赋值运算符是 implicitly-defined 并且没有采用 std::initializer_list
.
的构造函数或赋值运算符
std::initializer_list<int> l = {1, 2, 3};
std::array<int, 3> a = l; // doesn't work
a = l; // doesn't work
您可以将 std::initializer_list
视为一个容器 class,它专门用于使用 obj{args...}
语法的 ctor 参数。
下面,它包含一个临时 c-array,带有 size()
和指向 begin()
和 end()
的指针。 std::initializer_list
到 std::array
.
之间没有隐式转换
其他帖子已经提到了这样做的方法,你可以做的另一种方法是
std::copy(list.begin(), list.begin() + data.size(), data.begin());
即使您的 list.size()
大于 data.size()
。
请注意,如果 list.size()
小于 data.size()
,超出 list.size()
的任何内容都将被默认初始化,这将导致标量类型出现 ub。
我有一个模板 vec<T>
class 用于长度等于 3 的数学向量。
它看起来像这样:
template <typename T>
class vec{
public:
vec() { /**/ }
vec(std::initializer_list<T> list) { /**/ }
private:
std::array<T, 3> data;
};
我知道,可以这样用 std::initializer_list
初始化 std::array
:
std::array<int, 3> a = {1, 2, 3};
所以我想要一个带有 std::initializer_list
的构造函数来初始化我的向量,如下所示:
vec<int> v = {1, 2, 3};
我也有一个解决方案:只需遍历 std::initializer_list
个元素并写入 data
:
vec(std::initializer_list<T> list) {
size_t i = 0;
for (auto it = list.begin(); it != list.end(); it++) {
data[i++] = *it;
}
}
我试图让构造函数看起来像这样(因为 std::array
有一个带有 std::initializer_list
的构造函数):
vec(std::initializer_list<T> list) {
data = list;
}
但是当我尝试编译程序时,出现错误:
no match for ‘operator=’ (operand types are ‘std::array<int, 3>’ and ‘std::initializer_list<int>)’
这里有什么问题?为什么我不能以这种方式使用初始化列表初始化 std::array
?
作为一种可能的 work-around,您可以添加一个采用 std::array
的构造函数重载,并使用构造函数初始化列表(不要与 std::initializer_list
混淆)来初始化 data
:
vec(std::array<T, 3> const& list)
: data{ list }
{
}
Why can't I initialize
std::array
with initializer list in such a way?
Braced-init-list 和 std::initializer_list
are not the same thing. (Even std::initializer_list
could be constructed from braced-init-list.) std::array
is an aggregate and could be aggregate-initialized 或由 braced-init-list 分配为
std::array<int, 3> a = {1, 2, 3};
a = {4, 5, 6}; // convert {4, 5, 6} to std::array then assign to a
请注意 {1, 2, 3}
和 {4, 5, 6}
都是 braced-init-list 而不是 std::initializer_list
。
std::array
无法从 std::initializer_list
初始化(或分配);它的构造函数和赋值运算符是 implicitly-defined 并且没有采用 std::initializer_list
.
std::initializer_list<int> l = {1, 2, 3};
std::array<int, 3> a = l; // doesn't work
a = l; // doesn't work
您可以将 std::initializer_list
视为一个容器 class,它专门用于使用 obj{args...}
语法的 ctor 参数。
下面,它包含一个临时 c-array,带有 size()
和指向 begin()
和 end()
的指针。 std::initializer_list
到 std::array
.
其他帖子已经提到了这样做的方法,你可以做的另一种方法是
std::copy(list.begin(), list.begin() + data.size(), data.begin());
即使您的 list.size()
大于 data.size()
。
请注意,如果 list.size()
小于 data.size()
,超出 list.size()
的任何内容都将被默认初始化,这将导致标量类型出现 ub。