为什么数组元素<T*,N>的默认初始化需要C++ 14?

And*_*ger 2 c++ arrays c++11 c++14

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

#include <cstdlib>
#include <array>
template<size_t N> constexpr std::array<void*, N> empty_array{};
Run Code Online (Sandbox Code Playgroud)

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

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

我不明白为什么.根据http://en.cppreference.com/w/cpp/container/array,array<T, N>存在自C++ 11和隐式声明的构造函数

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

http://en.cppreference.com/w/cpp/language/aggregate_initialization上链接到聚合初始化的描述之后,它说

如果初始化程序子句的数量小于成员数或初始化程序列表完全为空,则其余成员将进行值初始化.

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

Jar*_*d42 9

C++ 14中引入了变量模板,请参阅http://en.cppreference.com/w/cpp/language/variable_template

  • @AndreasUnterweger`template <size_t N> constexpr std :: array <void*,N> empty_array {};`是一个变量模板. (5认同)
  • @AndreasUnterweger变量模板是一个模板化的变量,你混淆变量模板和[variadic template](https://en.wikipedia.org/wiki/Variadic_template). (5认同)
  • @AndreasUnterweger:也许你想要:`constexpr std :: array <void*,42> empty_array {};`相反.目前,您的`N`不是固定的,而是模板参数. (3认同)
  • @AndreasUnterweger - 你不是在解析**变量; 你宣布了​​一组变量; 每个`N`一个 (2认同)
  • @AndreasUnterweger - 好; 你所做的是被定义为"变量模板",从C++ 14开始提供. (2认同)

Jon*_*ely 9

要声明array5个元素:

constexpr std::array<void*, 5> empty_array{};
Run Code Online (Sandbox Code Playgroud)

要声明array10个元素:

constexpr std::array<void*, 10> empty_array{};
Run Code Online (Sandbox Code Playgroud)

要声明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>);
}
Run Code Online (Sandbox Code Playgroud)

但这是一个变量模板,这是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);
}
Run Code Online (Sandbox Code Playgroud)

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