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

rob*_*.14 28 c++

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

std::array<std::string, 42> a1;
std::array<int, a1.size()> a2;
Run Code Online (Sandbox Code Playgroud)

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

std::array<std::string, 42> a1;
std::array<int, sizeof(a1)/sizeof(a1[0])> a2;
Run Code Online (Sandbox Code Playgroud)

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

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

std::array<std::string, 42> a1;
std::array<int, std::tuple_size<decltype(a1)>::value> a2;
Run Code Online (Sandbox Code Playgroud)

Ada*_*son 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是为什么`size()`应该是一个`静态`函数,如问题所示. (7认同)
  • 实际上,标准库中已经有一个这样的“ array_size”推论模板:[`std :: tuple_size &lt;some_array_type&gt; :: value`](https://en.cppreference.com/w/cpp/utility/tuple / tuple_size)(C ++ 11)。在C ++ 17中,您还会发现通常的便利助手`std :: tuple_size_v &lt;some_array_type&gt;`。 (3认同)

chr*_*ris 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
Run Code Online (Sandbox Code Playgroud)

我猜这只是在GCC中实施它的人.


经过测试,这有效:

std::array<int, 42> a1;
std::array<int, a1.size()> a2;
Run Code Online (Sandbox Code Playgroud)

这可能实际上与std::string不是constexpr制作编译时实例的有效类型有关,而是int.