6

数日前に均一な初期化を発見しました。誰もが可能な限りそれを使用する必要があることをどこでも見ています。

しかし、この新しい構文は価値があるよりも面倒だと思わずにはいられません...


最初の例

次のような構造体を持つライブラリを作成するとします。

struct MyStruct
{
    int member0;
    int member1;
}

ユーザーは、集計の初期化を使用して次のように書くことができます。

MyStruct myVar = {0, 1}; // member0 = 0 and member1 = 1

ここで、ライブラリを更新し、構造体が次のようになったとしましょう。

struct MyStruct
{
    int member0;
    int member1;

    MyStruct(int p0, int p1) : member0(p1), member1(p0){}
}

C++11 より前では、ユーザー コードはコンパイルを停止し、ユーザーはコードを書き直してコンストラクターを使用する必要がありました。しかし今、コードはコンパイルされ、均一な初期化として解釈されます:

MyStruct myVar = {0, 1}; // member0 = 1 and member1 = 0

ユーザーが知らないうちに、ライブラリを更新すると、コードが非常に異なることを行うようになります!


2 番目の例

さて、私のライブラリにこのようなクラスがあるとしましょう:

class MyClass
{
public:
    MyClass(int size, int default = 0) : elements(size, default){}
private:
    std::vector<int> elements;
}

ユーザーは次のように使用できます。

MyClass myVar (3,1);  // 3 elements with value 1

または、次のように均一な初期化を使用します。

MyClass myVar {3,1};  // 3 elements with value 1

繰り返しになりますが、ライブラリを更新するとしましょう。クラスは次のようになります。

class MyClass
{
public:
    MyClass(int size, int default = 0) : elements(size, default){}
    MyClass(std::initializer_list<int> elts) : elements(elts){}
private:
    std::vector<int> elements;
}

古典的なコンストラクタが使用された場合、問題はありません:

MyClass myVar (3,1);  // 3 elements with value 1

ただし、均一な初期化が呼び出された場合、コードの解釈は変わります:

MyClass myVar {3,1};  // 2 elements with values 3 and 1

これらの例に基づいて、ユーザーが均一な初期化を使用することは非常に危険であるように思われます。使用されるライブラリに何かが追加されると、コードの解釈がまったく警告なしに変更される可能性があるためです。

さらに悪いことに、均一な初期化の導入により、集約の初期化が危険なものになります。

私は何かを逃しましたか?均一な初期化の使用が安全で便利なコンテキストはありますか?

4

1 に答える 1

8

あなたが対処した両方の問題は、均一な初期化自体とはほとんど関係がないと思いますが、インターフェイスを変更することの危険性を示しています。

次のようにライブラリを更新することで、ユーザー コードのまったく同じ次善の変更をアーカイブできます。

struct MyStruct
{
    int member1;
    int member0;
}

一様な初期化は含まれていません。c++11 より前のバージョンでは、オーバーロードの解決によって選択されたコンストラクターを変更することもできました。

class some_class
{
    public:
    some_class(int);
}

ユーザーコーダー:

some_class var(1.0);

コードが次のように変更された場合:

class some_class
{
    public:
    some_class(int);
    some_class(double);
}

2 番目のコンストラクターが呼び出されます。ここでも、一様な初期化は行われませんが、同じ問題が発生します。

したがって、両方の例は、ユーザー コードの意味がライブラリ インターフェースの変更によって変更される可能性があるという事実を示していますが、これは均一な初期化によって引き起こされた、または固有の問題ではなく、最適化されていない設計です。これは、ライブラリ インターフェイスを非常に慎重に設計する必要があるという事実を示しているにすぎません。

逆に、均一な初期化にはいくつかの真の利点があります。それらについては、この優れた回答を参照してください

于 2014-05-04T13:39:37.347 に答える