9

現代の C++ イニシャライザ リストは、オブジェクトを初期化するのに非常に便利であり、独自のコンストラクタを定義する必要がなくなると考えています。

struct point
{
    float coord[3];
};

point p = {1.f, 2.f, 3.f}; // nice !

ただし、クラスが別のクラスから継承されている場合、これは機能しません。

template<typename T>
class serializable
{
    protected:
        serializable() = default;
    ...
    // other stuff
}

struct point : public serializable<point>
{
    float coord[3];
};
point p = {1.f, 2.f, 3.f}; // Doesn't work :(

ポイントクラスに追加しようとしpoint() = default;ましたが、それもうまくいきませんでした。初期化子リストでポイントを初期化するにはどうすればよいですか?

4

1 に答える 1

10

元のケースは、集計の初期化 [dcl.init.list] に依存していました。

型 T のオブジェクトまたは参照のリスト初期化は、次の ように定義されます

T

[dcl.init.aggr] からの集計と集計の初期化は、次のように強調されます。

集約は、ユーザー提供のコンストラクター (12.1)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラス (条項 10)、および仮想関数 (10.3 ) を持たない配列またはクラス (条項 9) です。 )。

8.5.4 で指定されているように、初期化子リストによって集合体が初期化されると、初期化子リストの要素は、添え字またはメンバーの昇順で、集合体のメンバーの初期化子として取得されます。各メンバーは、対応する初期化句からコピー初期化されます。

しかし現在、point基本クラス ( serializable<point>)pointがあるため、集約ではなくなり、集約の初期化をサポートしなくなりました。

解決策は、そのようなコンストラクターを初期化するために単純に提供することですpoint:

struct point : public serializable<point>
{
    template <typename... T>
    point(T... ts) 
    : coord{ts...}
    { } 

    float coord[3];
};
于 2015-04-30T14:24:08.077 に答える