在编译时获取std :: array中的元素数量

时间:2013-05-31 21:09:43

标签: c++

以下是有效的C ++代码,为什么不呢?

std::array<std::string, 42> a1;
std::array<int, a1.size()> a2;

它不能在GCC 4.8中编译(在C ++ 11模式下)。有一个简单但不优雅的解决方法:

std::array<std::string, 42> a1;
std::array<int, sizeof(a1)/sizeof(a1[0])> a2;

很明显,编译器可以计算出std :: array中的元素数量。为什么std :: array :: size()不是constexpr static函数?

编辑: 我找到了另一种解决方法:

std::array<std::string, 42> a1;
std::array<int, std::tuple_size<decltype(a1)>::value> a2;

4 个答案:

答案 0 :(得分:16)

array<T>::size()constexpr,但您不能以这种方式使用它,因为a1不是constexpr值。此外,它不能是constexpr,因为string不是文字类型。

但是,如果需要,可以通过推导size_t模板参数来解决此问题。例如:

#include <string>
#include <array>
#include <iostream>
using namespace std;

template<typename>
struct array_size;
template<typename T, size_t N>
struct array_size<array<T,N> > {
    static size_t const size = N;
};

array<string, 42> a1;
array<string, array_size<decltype(a1)>::size> a2;

int main() {
    cout << a2.size() << endl;
}

答案 1 :(得分:10)

std::array::size实际上要求符合C ++ 11标准的第23.3.2.1节constexpr

23.3.2.4 array::size [array.size]  
template <class T, size_t N> constexpr size_type array<T,N>::size() noexcept;  
Returns: N

我猜这只是在GCC中实现它的任何人。


经过测试,这有效:

std::array<int, 42> a1;
std::array<int, a1.size()> a2;

这实际上可能与std::string不是有效的constexpr类型来构建编译时实例,而int是。

答案 2 :(得分:3)

您可以使用与C ++ 98数组绑定检测一样的模板推理方法。

template<size_t N, typename T>
constant_integer<N> array_size( const std::array<T, N>& );

制作一个漂亮的宏包装并享受!

许多变体也是可能的,例如:

答案 3 :(得分:0)

它不是静态的,而是constexpr http://www.cplusplus.com/reference/array/array/size/
编辑:这可能不是一个错误,看看这个Error using a constexpr as a template parameter within the same class