web-dev-qa-db-ja.com

初期化子リストで一定サイズの配列を初期化する

以下に要約できる状況があります。

class Test
{

    Test();

    int MySet[10];

};

初期化子リストでMySetを初期化することは可能ですか?

この種の初期化リストのように:

Test::Test() : MySet({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {}

クラスの初期化子リストで定数サイズのメンバー配列を初期化する方法はありますか?

23
Serge

C++ 03では使用できませんが、C++ 11は拡張初期化リストを導入します。 C++ 11標準に準拠したコンパイラを使用している場合、実際に実行できます。

struct Test {
    Test() : set { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } { };
    int set[10];
};

上記のコードは、g++ -std=c++0x -c test.ccを使用して正常にコンパイルされます。


コメントで役に立つユーザーによって私の下で指摘されたように、このコードコンパイルしない MicrosoftのVC++コンパイラを使用して、cl。おそらく、誰かがstd::arrayを使用して同等のものがするかどうかを教えてくれますか?

#include <array>

struct Test {
  Test() : set { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } } { };
  std::array<int, 10> set;
};

これは、g++ -std=c++0x -c test.ccを使用しても問題なくコンパイルできます。

26
oldrinb

残念ながら、C++ 03では、初期化リストで配列を初期化することはできません。ただし、コンパイラが新しい場合はC++ 11でも可能です。

参照: initializer_listを使用してメンバー配列を初期化する方法

「Setは10個の整数の静的配列へのポインタにすぎないことを理解しています」

いいえ、それは間違っています。それはポインタではなく配列です。

コンストラクタの初期化子リストで引き続き初期化できます。

C++ 11中括弧の初期化をサポートしていないコンパイラ(Visual C++バージョン11以前の場合は頭に浮かぶ)では、以下に示すように、いくつかのフープをジャンプする必要があります。

#include <iostream>
#include <vector>
using namespace std;

#define CPP11
#if defined( _MSC_VER )
#   if (_MSC_VER <= 1700)
#       undef CPP11
#   endif
#endif

#ifdef CPP11
class Cpp11
{
private:
    int set_[10];

public:
    Cpp11()
        : set_{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
    {}

    int foo() const { return set_[3]; }
};
#endif

class Cpp03
{
private:
    struct IntArray10 { int values[10]; };
    IntArray10 set_;

    static IntArray10 const& oneToTen()
    {
        static IntArray10 const values =
            { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} };
        return values;
    }

public:
    Cpp03()
        : set_( oneToTen() )
    {}

    int foo() const { return set_.values[3]; }
};

int main()
{}

ただし、生の配列を使用する代わりに、std::vectorおよびC+++ 11 std::array、どちらもVisual C++ 11でもサポートされています。