2016-09-11 8 views
0

initializer_list<string> ls = {"A", "B", "C"};はなぜ機能するのですか?テンプレートの矛盾に関する規則

rhsはintializer_list<const char*>です。どのようにlhsに変換されるのでしょうか。

同様に、vector<string> vs = {"A", "B", "C"}はどのように機能しますか?

答えて

0

RHSは、これは間違っているintializer_list<const char*>

です。右手側にはタイプがありません。タイプinitializer_listのオブジェクトではありません。 braced-init-listは、いくつかのコンテキストで使用される言語の特別な構文です。次のようにオブジェクトまたは型Tの参照の

一覧 - 初期化が定義されています:

[dcl.init.list]/3はこれがあなたの最初の質問について述べている
[... ]
- がstd::initializer_list<E>の特殊化である場合、prvalue initializer_listオブジェクトは以下のように構築され、同じタイプのクラス(8.5)からオブジェクトを初期化するルールに従ってオブジェクトを初期化するために使用されます。

[dcl.init.list]/5

実装タイプのN要素の一時的な配列を割り当てられているかのよう種類std::initializer_list<E>のオブジェクトが初期化リストから構成されていますconst Eここで、Nは、initializer listの要素の数です。その配列の各要素は、初期化子リストの対応する要素でコピー初期化され、std::initializer_list<E>オブジェクトはその配列を参照するように構築されます。 [注:コピー用に選択されたコンストラクタまたは変換関数は、イニシャライザリストのコンテキストでアクセス可能(第11条)しなければならない。 -end note]要素のいずれかを初期化するために変換を狭くする必要がある場合、プログラムは不正です。要するに

  1. 最初に、それはINIT-リストからの対応する要素と各文字列を初期化しようとする3列

  2. の配列にメモリを割り当てます。リストのすべての要素はconst char*に変換可能であり、std::stringにはconst char*を受け入れるコンストラクタがあるため、これらの文字列を構築するために使用されます。

2番目の質問では、もう1つの句は[dcl.init。リスト]/3使用される次のようなタイプTのオブジェクト又は基準の

リスト初期化が定義されている:
[...]
- そうでない場合、Tはクラス型である場合、コンストラクタ考えられています。該当するコンストラクタが列挙され、最適なものが過負荷解決(13.3、13.3.1.7)によって選択されます。引数のいずれかを変換するために狭い変換(下記参照)が必要な場合、プログラムは不正です。

vector<string>は、initializer_list<string>となるコンストラクタを有する。このケースでは最も合っており、ステージ1に戻ります。initializer_list<string>braced-init-listから構築する必要があります。これは既にわかっています。