【问题标题】:Why does the default initialization of the elements of an array<T*, N> require C++14?为什么 array<T*, N> 的元素的默认初始化需要 C++14?
【发布时间】:2018-07-17 18:45:59
【问题描述】:

考虑以下 MWE (https://godbolt.org/g/aydjpW):

#include <cstdlib>
#include <array>
template<size_t N> constexpr std::array<void*, N> empty_array{};

我的目标是拥有一个大小为N 的数组,其中每个元素都是默认初始化的(在这个MWE 的情况下,一个nullptr)。带有-std=c++11 的 g++ 5.4.0 抱怨

变量模板仅适用于 -std=c++14 或 -std=gnu++14

我不明白为什么。根据http://en.cppreference.com/w/cpp/container/arrayarray&lt;T, N&gt; 存在于 C++11 和隐式声明的构造函数

按照聚合初始化的规则初始化数组

点击http://en.cppreference.com/w/cpp/language/aggregate_initialization聚合初始化描述的链接,上面写着

如果初始化子句的数量小于 成员或初始化列表完全为空,其余成员 是值初始化的。

因此,我的假设是我上面的代码是有效的 C++11。我在这里缺少什么变量模板以某种方式涉及,这需要 C++14?

【问题讨论】:

  • 你不是在声明一个数组,你是在声明一个变量模板
  • 我认为你的困惑来自variable这个词的含义。错误消息中的词 variable 不是指 variable number of template arguments。它指的是(全局)变量empty_array,因为不能在变量前面使用template &lt;...&gt;(C++14 之前)。

标签: c++ arrays c++11 c++14


【解决方案1】:

要声明一个包含 5 个元素的 array

constexpr std::array<void*, 5> empty_array{};

要声明一个包含 10 个元素的 array

constexpr std::array<void*, 10> empty_array{};

要声明一个 N 元素的数组,其中 N 不固定,您需要使用一个模板,该模板可以针对不同的 N 值进行实例化:

// A variable of type std::array<void*, N> where N is not fixed yet:
template<size_t N> constexpr std::array<void*, N> empty_array{};

// Then given a function like this:
void do_something(const std::array<void*, 5>&);

// You use the variable like this, by giving the value of N:
void some_function() {
  do_something(empty_array<5>);
}

但这是一个变量模板,它是 C++14 中的一个新特性。您不能在 C++11 中执行此操作,因此会出现编译器错误。

要么使用 C++14,要么做类似的事情:

// An alias template defining a _type_ of array with no fixed N:
template<std::size_t N>
  using voidptr_array = std::array<void*, N>;

constexpr voidptr_array<5> empty_array_of_5{};
constexpr voidptr_array<10> empty_array_of_10{};

void do_something(const std::array<void*, 5>&);

void some_function() {
  do_something(empty_array_of_5);
}

这个别名模板定义了一个以 N 作为参数的 type,而不是一个以 N 作为参数的 variable。您仍然需要定义该类型的变量,例如 empty_array_of_5empty_array_of_10

【讨论】:

    【解决方案2】:

    【讨论】:

    • @AndreasUnterweger template&lt;size_t N&gt; constexpr std::array&lt;void*, N&gt; empty_array{}; 是一个变量模板。
    • @AndreasUnterweger:也许你想要:constexpr std::array&lt;void*, 42&gt; empty_array{};。目前,你的N不是固定的,而是一个模板参数。
    • @AndreasUnterweger - 你没有删除 a 变量;您正在声明一组变量;每个N一个
    • @AndreasUnterweger 变量模板是一个被模板化的变量,你混淆了变量模板和variadic template
    • @AndreasUnterweger - 好;你所做的被定义为“变量模板”,并且从 C++14 开始可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 2021-10-10
    • 2021-06-13
    • 2016-04-26
    • 1970-01-01
    相关资源
    最近更新 更多