3

標準テキストには、8.5.4(3)リスト初期化[dcl.init.list]の例があります。

struct S {
    S(std::initializer_list<double>);  // #1
    S(const std::string&);             // #2
};
const S& r1 = { 1, 2, 3.0 };  // OK: invoke #1
const S& r2 { "Spinach" };    // OK: invoke #2 !!!

(例はref-to-tempに関するものですが、ここでは過負荷の解決を参照します)。

スコット・マイヤーズが彼の講演/スライドで別の話をしているのに対し、

std :: initializer_listパラメーターは、他のタイプよりも常に優先されます。

class Widget {
public:
    Widget(double value, double uncertainty);           // #1
    Widget(std::initializer_list<std::string> values);  // #2
};
double d1, d2;
Widget w1 { d1, d2 }; // tries to call #2; fails because
                      // no double ⇒ string conversion

例は少し異なりますが、同じものではありませんか?-コンストラクターによる過負荷の解決はinitializer_listいつどのように行われますか?または、ここに別の問題がありますか?

どちらの場合も、オーバーロードはどのように決定されますか?両方が正しければ、ここで何が恋しいですか?

ケリックのコメントの編集/明確化:私の気持ちは、2つの例が互いに矛盾しているということです:

  • Stdは、aがaconst char*に変換される例を示しています。これは、提供されたものとstring一致しないinitializer_list<int>ため、提供された「通常の」const string&-c'torが使用されます。
  • スコットの例は{double, double}、-c'torが利用可能であり、したがって選択されたときに初期化さintializer_list<int>れます。これは、リストが優先されるためです。したがって、(double, double)この方法で初期化されたときに、提供された-c'torが選択されることはありません。

もちろん、Stdは常に正しいですが、例を間違って適用している可能性があります。Stdの例には&、私の質問には関係ないと思うが、おそらく私は間違っているということが含まれています。

スコットのスライドはごく最近のものであり、Stdの関連するセクションがその点に変更されていることはわかりません(ただし、ある程度「広く普及している」ため、すべてを範囲に収めることは困難です:-)

編集-2 :スライドに組み込まれていなかった標準の変更が遅れたというスコット自身からのメールを受け取りました。

4

1 に答える 1

5

2011年4月5日からのワーキングドラフトであるN3291に従って、初期化子リストにいくつかの変更が加えられたため、ScottMeyerのスライドは古いデータのものである可能性があります。

セクション13.3.1.7(1337に非常に近い)によると:

  • 当初、候補関数はクラスTの初期化子リストコンストラクター(8.5.4)であり、引数リストは単一の引数としての初期化子リストで構成されます。
  • 実行可能な初期化子リストコンストラクターが見つからない場合、オーバーロード解決が再度実行されます。候補関数はクラスTのすべてのコンストラクターであり、引数リストは初期化子リストの要素で構成されます。

したがって、それはイニタイライザーリストを好みます。ただし、初期化子リストが一致しない場合は、通常のコンストラクターをチェックして、それらが一致するかどうかを確認します。

さらに、初期化子リストが空の場合、デフォルトのコンストラクターが使用されます。

于 2011-07-19T11:07:02.940 に答える