#include <iostream>
#include <string>
#include <initializer_list>
class A
{
public:
A(int, bool) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(int, double) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(std::initializer_list<int>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int main()
{
A a1 = {1, 1.0};
return 0;
}
(この質問はこれのフォローアップです。)
上記のプログラムはコンパイルに失敗しますclang35 -std=c++11
init.cpp:15:14: error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
A a1 = {1, 1.0};
^~~
init.cpp:15:14: note: insert an explicit cast to silence this issue
A a1 = {1, 1.0};
^~~
static_cast<int>( )
while をg++48 -std=c++11
選択すると、不適切な形式の狭小化を診断するための警告が生成されます
init.cpp: In function ‘int main()’:
init.cpp:15:17: warning: narrowing conversion of ‘1.0e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
A a1 = {1, 1.0};
^
init.cpp:15:17: warning: narrowing conversion of ‘1.0e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
結果を生成します
A::A(std::initializer_list<int>)
私の質問はA::A(std::initializer_list<int>)
、実行可能な過負荷にする必要があるかどうかです。initializer_list
以下は、過負荷が実行可能であってはならないことを暗示していると思われる標準的な引用です。
から13.3.2 [over.match.viable]
第 2 に
F
、実行可能な関数であるためには、各引数に対して、その引数を の対応するパラメーターに変換する暗黙の変換シーケンスが存在する必要がありますF
。
から4 [conv]
宣言が次の場合にのみ、式を暗黙的に型に変換でき
e
ます。いくつかの発明された一時変数の場合、整形式です。T
T t=e
t
から8.5.1 [dcl.init.aggr]
initializer-clauseが式であり、式を変換するために縮小変換が必要な場合、プログラムは不適切な形式です。
以下は整形式ではないため、8.5.1
andを使用します。4
std::initializer_list<int> e = {1, 1.0};
{1, 1.0}
は に暗黙的に変換できませんstd::initializer_list<int>
。
からの引用を使用すると、 のオーバーロード解決を行うときに実行可能な関数13.3.2
ではないことを意味するべきではありませんか? 実行可能なコンストラクターが見つからない場合、このステートメントは を選択すべきではありませんか?A::A(std::initializer_list<int>)
A a1 = {1, 1.0};
initializer_list
A::A(int, double)