このコードを考えてみましょう:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
この版画:
vector overload
int overload
なぜこれが原因あいまいなオーバーロードの解決にコンパイルエラーを生成しませんか?二コンストラクタが削除された場合、我々が得るvector overload
2回。どのように/メトリック何によってであるint
ため、明確に、より良い試合{}
よりはstd::vector<int>
?
コンストラクタの署名が確実にさらにトリミングすることができますが、私は、単にコードの同等の部品によってだまされてしまったし、この質問のために失われていることを確認何が重要なようにしたいです。
それは中です[over.ics.list] 、重点鉱山
6そうでない場合、パラメータは[over.match.list]あたりの非集約クラスXおよび過負荷解像度である場合には、リスト初期化引数の型Xのオブジェクトの初期化を実行するためにXの単一の最良コンストラクタCを選択します。
Cである場合には初期リストコンストラクタないと初期化リストは、単一の要素有する UがX又はXから派生したクラスであるタイプCV UのをUがX、または変換ランク場合であれば、暗黙的な変換シーケンスは、完全一致のランクを有しますUはXから導出され
そうでない場合は、暗黙の変換シーケンスは、第二の標準変換シーケンス恒等変換とユーザ定義の変換シーケンスです。
9それ以外の場合は、パラメータの型がクラスでない場合:
[...]
初期化子リストに要素がない場合は、暗黙的な変換シーケンスが恒等変換です。[例:
void f(int); f( { } ); // OK: identity conversion
端例]
std::vector
コンストラクタと大胆と見なして、ユーザー定義のconverisonで銃弾によって初期化されます。一方、のためにint
、これは恒等変換であるので、最初c'torのランクを切り札。