37

重複の可能性:
initializer_listを使用してメンバー配列を初期化するにはどうすればよいですか?

初期化子リストを使用して、std::arrayを適切に作成できます。

std::array<int, 3> a = {1, 2, 3};  // works fine

ただし、クラスのデータメンバーまたはベースオブジェクトとしてから構築しようとするとstd::initializer_list、機能しません。

#include <array>
#include <initializer_list>

template <typename T, std::size_t size, typename EnumT>
struct enum_addressable_array : public std::array<T, size>
{
    typedef std::array<T, size> base_t;
    typedef typename base_t::reference reference;
    typedef typename base_t::const_reference const_reference;
    typedef typename base_t::size_type size_type;

    enum_addressable_array(std::initializer_list<T> il) : base_t{il} {}

    reference operator[](EnumT n)
    {
        return base_t::operator[](static_cast<size_type>(n));
    }

    const_reference operator[](EnumT n) const
    {
        return base_t::operator[](static_cast<size_type>(n));
    }
};

enum class E {a, b, c};
enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};

gcc 4.6のエラー:

test.cpp: In constructor 'enum_addressable_array<T, size, EnumT>::enum_addressable_array(std::initializer_list<T>) [with T = char, unsigned int size = 3u, EnumT = E]':
test.cpp:26:55:   instantiated from here
test.cpp:12:68: error: no matching function for call to 'std::array<char, 3u>::array(<brace-enclosed initializer list>)'
test.cpp:12:68: note: candidates are:
include/c++/4.6.1/array:60:12: note: std::array<char, 3u>::array()
include/c++/4.6.1/array:60:12: note:   candidate expects 0 arguments, 1 provided
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(const std::array<char, 3u>&)
include/c++/4.6.1/array:60:12: note:   no known conversion for argument 1 from 'std::initializer_list<char>' to 'const std::array<char, 3u>&'
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(std::array<char, 3u>&&)
include/c++/4.6.1/array:60:12: note:   no known conversion for argument 1 from 'std::initializer_list<char>' to 'std::array<char, 3u>&&'

ラッパークラスをinitializer-listで初期化できるようにするには、どうすればよいですか。

enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};
4

3 に答える 3

37

std::array<>は(初期化子リストコンストラクター)を受け取るコンストラクターがなく、クラスのコンストラクターにstd::initializer_list<>を渡すことの意味についての特別な言語サポートはありません。std::initializer_list<>だからそれは失敗します。

それが機能するためには、派生クラスがすべての要素をキャッチしてから、それらをコンストラクターテンプレートとして転送する必要があります。

template<typename ...E>
enum_addressable_array(E&&...e) : base_t{{std::forward<E>(e)...}} {}

{{...}}この場合、中括弧の省略(あなたの場合のように中括弧を省略する)はその場所では機能しないため、必要であることに注意してください。フォームの宣言でのみ許可されT t = { ... }ます。std::array<>は生の配列を埋め込む構造体で構成されているため、 2レベルの中括弧が必要になります。残念ながら、の正確な集計構造std::array<>は指定されていないと思います。そのため、ほとんどの実装で機能することを期待する必要があります。

于 2011-08-01T04:22:16.927 に答える
32

astd::arrayは集合体を含む構造体であるため(それ自体は集合体ではなく、を受け取るコンストラクターもありませんstd::initializer_list)、次のような中括弧構文を使用して、構造内の基になる集合体を初期化子リストで初期化できます。

std::array<int, 4> my_array = {{1, 2, 3, 4}};

これは使用していないことに注意してくださいstd::initializer_list...これは、C++初期化子リストを使用しての公的にアクセス可能な配列メンバーを初期化するだけですstd::array

于 2011-08-01T03:57:52.137 に答える
10

std::arrayは、をとるコンストラクターはありませんstd::initializer_list。イニシャライザリストは配列の固定サイズよりも大きくなる可能性があるため、これは良いことです。

初期化子リストが配列のサイズより大きくないことをテストしてから、初期化子リストの要素をwithのelemsメンバーにコピーすることで初期化できます。std::arraystd::copy

于 2011-08-01T03:09:14.727 に答える