[英]no match for operator '=' (std::array<T, 3> and std::initializer_list<T>)
I have a template vec<T>
class for math vectors with constant length is equal to 3. It looks like this:我有一个模板
vec<T>
类,用于常量长度等于 3 的数学向量。它看起来像这样:
template <typename T>
class vec{
public:
vec() { /**/ }
vec(std::initializer_list<T> list) { /**/ }
private:
std::array<T, 3> data;
};
I know, that it is possible to initialize std::array
with an std::initializer_list
in such a way:我知道,可以通过这种方式使用
std::initializer_list
初始化std::array
:
std::array<int, 3> a = {1, 2, 3};
So I would like to have a constructor with an std::initializer_list
to initialize my vector like this:所以我想要一个带有
std::initializer_list
的构造std::initializer_list
来像这样初始化我的向量:
vec<int> v = {1, 2, 3};
I also have a solution for this: just iterate through std::initializer_list
elements and write to data
:我也有一个解决方案:只需遍历
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;
}
}
I tried to make constructor look like this (because of std::array
has a constructor with std::initializer_list
):我试图让构造函数看起来像这样(因为
std::array
有一个带有std::initializer_list
的构造std::initializer_list
):
vec(std::initializer_list<T> list) {
data = list;
}
But when I try to compile a program, the error occurs:但是当我尝试编译程序时,出现错误:
no match for ‘operator=’ (operand types are ‘std::array<int, 3>’ and ‘std::initializer_list<int>)’
What's the problem here?这里有什么问题? Why can't I initialize
std::array
with initializer list in such a way?为什么我不能以这种方式用初始化列表初始化
std::array
?
Why can't I initialize
std::array
with initializer list in such a way?为什么我不能以这种方式用初始化列表初始化
std::array
?
Braced-init-list and std::initializer_list
are not the same thing. Braced-init-list 和
std::initializer_list
不是一回事。 (Even std::initializer_list
could be constructed from braced-init-list.) std::array
is an aggregate and could be aggregate-initialized or assigned by braced-init-list as (甚至
std::initializer_list
也可以从braced-init-list 构造。) std::array
是一个聚合并且可以被聚合初始化或由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
Note that both {1, 2, 3}
and {4, 5, 6}
are braced-init-list but not std::initializer_list
.请注意,
{1, 2, 3}
和{4, 5, 6}
都是花括号初始化列表,但不是std::initializer_list
。
std::array
can't be initialized (or assigned) from an std::initializer_list
; std::array
不能从std::initializer_list
初始化(或赋值); its constructors and assignment operator are implicitly-defined and doesn't have such constructor or assignment operator taking std::initializer_list
.它的构造函数和赋值运算符是隐式定义的,并且没有这样的构造函数或赋值运算符采用
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
As a possible work-around, you could add a constructor overload taking a std::array
instead, and use a constructor initializer list (not to be confused with std::initializer_list
) to initialize data
:作为一种可能的解决方法,您可以添加一个采用
std::array
的构造函数重载,并使用构造函数初始值设定项列表(不要与std::initializer_list
混淆)来初始化data
:
vec(std::array<T, 3> const& list)
: data{ list }
{
}
You can think of std::initializer_list
as a container class that works specifically for ctor parameters with the obj{args...}
syntax.您可以将
std::initializer_list
视为一个容器类,它专门用于使用obj{args...}
语法的 ctor 参数。
Underneath, it contains a temporary c-array, with size()
and pointer to begin()
and end()
.在下面,它包含一个临时 c 数组,带有
size()
和指向begin()
和end()
指针。 And there isn't a implicit conversion between std::initializer_list
to std::array
.并且
std::initializer_list
到std::array
之间没有隐式转换。
Other posts already mentioned ways of doing it, another way you could do is其他帖子已经提到了这样做的方法,另一种方法是
std::copy(list.begin(), list.begin() + data.size(), data.begin());
This would work even if your list.size()
is larger than data.size()
.即使您的
list.size()
大于data.size()
这也会起作用。
Do note that if list.size()
is smaller than data.size()
, anything pass beyond list.size()
would be default initialized, which would cause ub for scalar types.请注意,如果
list.size()
小于data.size()
,则超出list.size()
任何内容都将被默认初始化,这将导致标量类型的 ub 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.