【问题标题】:How to initialize a class like std::array如何初始化像 std::array 这样的类
【发布时间】:2015-12-11 03:19:47
【问题描述】:

我正在尝试为向量算术编写一个容器类。对象的大小是静态的:

template<typename T, unsigned N>
class vec{
    T data[N] = {0};
public:
    vec(std::initializer_list<T> ini){
        std::copy(ini.begin(), ini.end(), data);
    }
}

这就是我的成绩。

但我测试了 std::array 类以进行比较,我注意到如果初始化列表太长或太短,它会以某种方式做出静态断言。

std::array<float, 2> a = {1, 2, 3, 4} <- instant error message from the visual studio ide

在我的课堂上,我必须在运行时检查初始化列表的长度。

我假设,std::array 类以某种方式管理它以使用初始化列表表示法直接初始化数据,而无需 std::initializer_list 类。

是否可以像 std::array 一样初始化我的类?

【问题讨论】:

  • 您的 vec 不允许这样做的一个原因是 T data[n] 是私有的......将其公开,然后摆脱构造函数。此外,如果您包含结束 ;

标签: arrays c++11 stl initialization stdarray


【解决方案1】:

std::array 是一个聚合,因此它使用aggregate initialization。在聚合初始化期间提供多余的元素是不正确的,需要进行诊断。编译器至少必须提供警告,gcc 和 clang 都会导致此错误。因此,如果您使您的类成为聚合,那么您可以让它以与 std::array 相同的方式工作。注意,in class member initializers makes your class a non-aggregate 在 C++11 中而不是在 C++14 中。

我们可以通过转到草案 C++11 标准部分 23.3.2.1 看到它是一个聚合[array.overview]

数组是一个聚合(8.5.1),可以用 语法

array<T, N> a = { initializer-list };

其中 initializer-list 是一个逗号分隔的列表,最多包含 N 个元素 其类型可转换为 T。

8.5.1[dcl.init.aggr] 部分涵盖了聚合初始化并说:

如果初始值设定项子句的数目不定,则初始值设定项列表格式错误 超过了要初始化的成员或元素的数量。

标准草案提供了一种可能的实现方式,该实现方式缩短到最低限度,如下所示:

template <class T, size_t N>
struct array {
    T elems[N];
};

标准草案有一个注释,上面写着:

成员变量 elems 仅用于说明,以强调数组是类聚合。 名称 elems 不是数组接口的一部分

这是一个聚合,如果提供了过多的元素,gcc 和 clang 都会提供错误。

另见What are Aggregates and PODs and how/why are they special?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    相关资源
    最近更新 更多