如何使用带有聚合初始化的 std::array 定义向量类?
Posted
技术标签:
【中文标题】如何使用带有聚合初始化的 std::array 定义向量类?【英文标题】:How to define a vector class using std::array with aggregate initialization? 【发布时间】:2020-01-14 14:53:21 【问题描述】:我这样定义一个类
#include<array>
template<class T,size_t D>
class vec
private:
std::array<T,D> arr;
public:
vec(std::initializer_list<T> l) : arr(l)
;
然后我这样构造这个类的对象。
vec<int,3> v = 1,2,3;
然后我得到一个错误
main.cpp:5:26: error: cannot bind non-const lvalue reference of type ‘std::initializer_list<int>&’ to an rvalue of type ‘std::initializer_list<int>’
vec<int,3> v = 1,2,3;
^
In file included from main.cpp:1:
vec.hpp:12:9: note: initializing argument 1 of ‘vec<T, D>::vec(std::initializer_list<_Tp>&) [with T = int; long unsigned int D = 3]’
vec(std::initializer_list<T>& l) : arr(l)
我想知道如何使构造函数中的聚合初始化有效。
【问题讨论】:
【参考方案1】:std::array
不能从 std::initializer_list
构造。如果您想保留 std::array
成员,您有两个选项可以解决此问题。您可以通过将arr
公开并删除构造函数来使vec
和聚合
#include<array>
template<class T,size_t D>
class vec
public:
std::array<T,D> arr;
;
int main()
vec<int,3> v = 1,2,3;
或者你保留它,但是你迭代arr
并从初始化列表中为其分配值。看起来像
#include<array>
template<class T,size_t D>
class vec
private:
std::array<T,D> arr;
public:
vec(std::initializer_list<T> l)
std::copy_n(l.begin(), std::min(l.size(), arr.size()), arr.begin());
;
int main()
vec<int,3> v = 1,2,3;
此方法确实要求数组成员是默认可构造的。如果您不能/不想保证,那么您需要选项一或切换到为arr
使用不同的类型,例如std::vector
。
【讨论】:
非常感谢。这真的很有帮助。你介意向我解释更多关于默认构造函数的信息吗?我想知道在类 vec 中是否有两个 std:: 数组成员 arr1 和 arr2,v=1,2,3 也可以吗?谢谢。 @Richard 在我的第二个示例中,因为我们在构造函数的主体中,这意味着arr
已经默认构造。为了实现这一点,这意味着 T
需要是具有默认构造函数的类型。如果T
是一个没有默认构造函数的类型,那么你会得到一个错误,因为这意味着它不能默认构造arr
。您可以为两个数组使用任何一种方法。您只需要使用两个列表,例如 vec v = 1,2,3,3,4,5
是的,我明白了。非常感谢您的帮助。【参考方案2】:
std::array
没有任何构造函数。它只有聚合初始化器。如果将std::array
替换为std::vector
它应该可以工作,因为vector 具有初始化列表构造函数。
【讨论】:
以上是关于如何使用带有聚合初始化的 std::array 定义向量类?的主要内容,如果未能解决你的问题,请参考以下文章
在 g++ 上进行聚合初始化的 std::array 会生成大量代码
如何使用初始化列表构造 std::array 对象? [复制]