6

最近、explicit指定子について学びました。

次があるとします。

f( W, W, W );

今私たちがするなら

f( 42, 3.14, "seven" );

コンパイラは、次の暗黙的な変換を試みます。

f( W(42), W(3.14), W("seven") );

W に一致するコンストラクターを定義した場合、つまり:

W(int);
W(double);
W(std::string);

...それは成功します。

ただし、最初のものを明示的にすると、次のようになります。

explicit W(int);

...これにより、暗黙的な変換が無効になります。

あなたは今書く必要があります:

f( W(42), 3.14, "seven" );

つまり、変換を明示的に述べる必要があります

質問に移りましょう:

次のように書くことができます。

explicit W(int,int); // 2 arguments!

これはコンパイルされます!

しかし、この構文を必要とする可能性のある対応するシナリオは見当たりません。

誰でも最小限の例を提供できますか?

4

1 に答える 1

11

コンストラクターが明示的であり、クラスが を受け取る非明示的なコンストラクターを提供しないinitializer_list<T>場合、インスタンスをコピー リスト初期化することはできません。

W w = {1,2}; // compiles without explicit, but not with

簡単な実例

#include <iostream>

class A
{
public:
   explicit A(int, int) {}
};

class B
{
public:
    B(int, int) {}
};

int main()
{
   B b = {1,2};
   A a = {1,2};
}

標準からの引用:

8.5/16

— 初期化子が (括弧で囲まれていない) 波括弧初期化リストである場合、オブジェクトまたは参照はリスト初期化されます (8.5.4)。

8.5.4/3

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

それ以外の場合、T がクラス型の場合、コンストラクターが考慮されます。適用可能なコンストラクターが列挙され、オーバーロード解決 (13.3、13.3.1.7) によって最適なコンストラクターが選択されます。引数のいずれかを変換するために縮小変換 (以下を参照) が必要な場合、プログラムは不適切な形式です。

于 2014-12-25T08:51:14.330 に答える