2016-08-13 2 views
1

次のコードを見ると、main()の両方の行がInitSomethinginitializer_listコンストラクタを呼び出す必要があります。 gccは私が期待した通り22を出力しますが、clangはただ一つの2を出力します。 clangは間違っていますか?Clangがイニシャライザリスト構築の処理をスキップします

-std=c++14とコンパイルしています。

#include <iostream> 

struct InitSomething { 
    explicit InitSomething(int) { std::cout << '1'; } 
    InitSomething(std::initializer_list<int>) { std::cout << '2'; } 
    operator int() { return 1; } 
}; 

int main() { 
    InitSomething init_something{1}; 
    InitSomething init_something_else{init_something}; 
} 

clang++ --versionの出力は、(私はMac上で午前)

Apple LLVM version 7.3.0 (clang-703.0.31) 
Target: x86_64-apple-darwin15.5.0 
Thread model: posix 
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin 

であり、私が言及した他のプラットフォーム上でg++ --versionの出力は

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+0

直接 'some_value'を取って他のコンストラクタがある場合**のためinitializer_list賛成していない、最近、' {} 'some_valueのあらゆる**セット言語への変更がありました。 –

+0

@BoPerssonあなたはC++ 17の権利を参照していますか? – Curious

+1

私はそれが現われた時が正確ではない。 (http://open-std.org/JTC1/SC22/ - 参照を探しています... –

答えて

2

DR1467のタイトルです集計には関心がありますが、the wording it added to [dcl.init.list]/3は最初の箇条書きとして集計に限定されませんATE:

Tクラス型であり、初期化子リストUT又はTから派生したクラスであるタイプcv Uの単一要素 を有する場合、 オブジェクトは著作によって(その要素から初期化されます コピーリスト初期化のための初期化、または ダイレクトリスト初期化のための直接初期化によって)。

しかし、DR2137バックこの文言(「集約クラス」と「クラスタイプ」を置き換える)から歩いていない、などthis bulletはもはやInitSomethingような非凝集体に適用されます。それは事前DR1467行ったよう

代わりに、[dcl.init.list] /3.6、適用されます。

をそれ以外の場合は、Tはコンストラクタが考慮され、クラス型である場合。 該当するコンストラクタが列挙され、オーバーロード解決([over.match]、 [over.match.list])によって最適なものが選択されます。

そして[over.match.list]は、初期化子リストのコンストラクタが好ましいことが明らかになり、すべての実行可能な場合:

非集計クラス型 Tのオブジェクトがあるよう リストが初期化されている

[dcl.init.list 】過負荷解像度がオーバーロード解決は、2つのフェーズで コンストラクタを選択し、この節の規則に従って 行われることを指定:

  • 最初に、候補関数はクラスTのイニシャライザリストコンストラクタ([dcl.init.list])であり、引数リスト は単一の引数としてイニシャライザリストで構成されています。生存可能な初期化リストコンストラクタが見つからない場合
  • 、オーバーロード解決を候補関数はクラスTと引数リストの全て コンストラクタである場合、再度実行される初期化子リストの の要素から構成されています。

暗黙的な変換シーケンスをランク付けについてのすべてのこの話は無関係です非初期化子リストのコンストラクタためにも候補者ではありません。

クランはDR1467後とDR2137前の文言を実施しています。

+0

このようなことから、私は真剣に 'initializer_list'を概念として質問します。 – Barry

関連する問題