如何使用带有聚合初始化的 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 初始化中的大括号省略

如何使用初始化列表构造 std::array 对象? [复制]

C ++ 11中的数组[重复]

如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N>

我应该如何大括号初始化 std::pairs 的 std::array?