33

以下是有效的 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

4 回答 4

20

array<T>::size()is constexpr,但你不能以这种方式使用它,因为a1is 不是一个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;
}
于 2013-05-31T21:16:28.313 回答
10

std::array::size实际上需要符合constexprC++11 标准的第 23.3.2.1 节:

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编译时实例的有效类型有关,而intis。

于 2013-05-31T21:12:04.763 回答
4

您可以使用与 C++98 数组边界检测相同的模板推断方法。

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

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

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

于 2013-05-31T21:18:22.510 回答
0

它不是静态的,但它是constexpr http://www.cplusplus.com/reference/array/array/size/
编辑:这可能不是一个错误,看看这个错误使用 constexpr 作为模板参数同班

于 2013-05-31T21:12:07.163 回答