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()はですが、値ではないconstexprため、このように使用することはできません。さらに、リテラル型ではないため、それはできません。a1constexprconstexprstring

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::sizeconstexpr実際には、C++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のに有効な型ではないことに関係している可能性があります。constexprint

于 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/
編集: これはバグではない可能性があります。同じクラス

于 2013-05-31T21:12:07.163 に答える