首页 > 解决方案 > 我想包装 std::array 来创建一个循环数组但是如何提供聚合初始化

问题描述

std::array你可以做

std::array<int,3> v = {1,2,3};

但我想提供一个包装

template <typename T, int n> circular_array {
   auto operator[](size_t i){
       return m_data[i%n];  
   }
   // TODO forward all other methods directly except ``at`` which we don't need
 private:
   std::array<t,n> m_data;
}

但我失去了上面的聚合初始化std::array。这行不通。

circular_array<int,3> v = {1,2,3};

虽然如果我m_data公开我可以做

circular_array<int,3> v = {{1,2,3}};

这是不希望的。

有没有办法实现包括聚合初始化circular_array的下降?std::array

标签: c++arraysc++14stdarrayaggregate-initialization

解决方案


不确定它是否正是您要查找的内容,但您可以使用继承(即从 派生您的类std::array)而不是组合(即具有std:array数据成员)。

这是一个演示:

#include <array>
#include <iostream>

template <typename T, int n>
class circular_array : public std::array<T, n>
{
public:
    auto operator[](size_t i) {
        return std::array<T, n>::data()[i % n];
    }
};

int main()
{
    circular_array<int, 3> v = {1,2,3};
    for (size_t i = 0; i < 10; ++i) {
        std::cout << v[i] << std::endl;
    }
    return 0;
}

我已经在 Visual Studio (Windows) 中测试了这段代码,它按预期工作;std:array本机 MSVC 编译器不提供诊断(即使在代码分析模式下),但 clang-cl 为聚合初始化发出以下内容(在对本机对象使用此类语法时不提供):

警告:建议在子对象初始化时使用大括号 [-Wmissing-braces]

不是语言律师,我不确定这是否意味着该circular_array<int, 3> v = {1,2,3};行仍然是聚合初始化;但是,如果不是,那么我同样不确定它是什么。


推荐阅读