C ++標準§13.3.1.7[over.match.list]では、次のように記述されています。
copy-list-initializationでは、
explicit
コンストラクターが選択されている場合、初期化の形式が正しくありません。
これが、たとえば次のようなことができない理由です。
struct foo {
// explicit because it can be called with one argument
explicit foo(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
f({ "answer", 42 });
(ここで行われるのは変換ではなく、コンストラクターが「暗黙的」であったとしても変換されないことに注意してください。これはfoo
、コンストラクターを直接使用したオブジェクトの初期化です。以外はstd::string
、ここでは変換はありません。)
これは私には完全に問題ないようです。暗黙の変換が私を噛む方法はありません。
{ "answer", 42 }
他の何かを初期化できる場合、コンパイラは私を裏切って間違ったことをしません:
struct bar {
// explicit because it can be called with one argument
explicit bar(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
void f(bar x);
f({ "answer", 42 }); // error: ambiguous call
問題はありません。呼び出しがあいまいで、コードがコンパイルされないため、オーバーロードを明示的に選択する必要があります。
f(bar { "answer", 42 }); // ok
禁止事項が明記されているので、ここで何かが足りない気がします。私が見る限り、明示的なコンストラクターを選択するリスト初期化は私には問題のようには思えません。リスト初期化構文を使用することにより、プログラマーはすでにある種の「変換」を実行したいという願望を表明しています。
何がうまくいかない可能性がありますか?私は何が欠けていますか?