g ++(4.7または4.8)がコンパイルを拒否するC++ 11コードの小片を持っていて、B2 b2a(x、 {P(y)})はあいまいです。 Clang ++はこのコードに満足していますが、g ++がコンパイルするのが完全にうれしいB2 b2b(x、{{P(y)}}をコンパイルすることを拒否しています!C++ 11のコンストラクタのオーバーロードの解決とinitialiser_lists:clang ++とg ++の同意がない
両方のコンパイラは、{...}または{{...}}を引数としてB1コンストラクタに完全に満足しています。どんなC++言語弁護士がどのコンパイラが正しいか(もしあれば)、何が起こっているのかを説明できますか?以下のコード:
#include <initializer_list>
using namespace std;
class Y {};
class X;
template<class T> class P {
public:
P(T);
};
template<class T> class A {
public:
A(initializer_list<T>);
};
class B1 {
public:
B1(const X&, const Y &);
B1(const X&, const A<Y> &);
};
class B2 {
public:
B2(const X &, const P<Y> &);
B2(const X &, const A<P<Y>> &);
};
int f(const X &x, const Y y) {
B1 b1a(x, {y});
B1 b1b(x, {{y}});
B2 b2a(x, {P<Y>(y)});
B2 b2b(x, {{P<Y>(y)}});
return 0;
}
とコンパイルエラー、打ち鳴らす:
$ clang++ -stdlib=libc++ -std=c++11 test-initialiser-list-4.cc -o test.o -c
test-initialiser-list-4.cc:32:6: error: call to constructor of 'B2' is ambiguous
B2 b2(x, {{P<Y>(y)}});
^~~~~~~~~~~~~~~
test-initialiser-list-4.cc:26:5: note: candidate constructor
B2(const X &, const P<Y> &);
^
test-initialiser-list-4.cc:27:5: note: candidate constructor
B2(const X &, const A<P<Y>> &);
^
グラム++:
test-initialiser-list-4.cc: In function 'int f(const X&, Y)':
test-initialiser-list-4.cc:32:21: error: call of overloaded 'B2(const X&, <brace-enclosed initializer list>)' is ambiguous
B2 b2(x, {P<Y>(y)});
^
test-initialiser-list-4.cc:32:21: note: candidates are:
test-initialiser-list-4.cc:27:5: note: B2::B2(const X&, const A<P<Y> >&)
B2(const X &, const A<P<Y>> &);
^
test-initialiser-list-4.cc:26:5: note: B2::B2(const X&, const P<Y>&)
B2(const X &, const P<Y> &);
^
これはテンプレートで過負荷に均一な初期化、初期化子リストの構文と機能の間の相互作用のようなにおい議論(私はg ++がかなり厳しいと知っています)しかし、私はここで正しい振る舞いでなければならないものを解くことができる標準弁護士ではありません!
2つのローカル変数と呼ばちょうど誤植と、問題の原因ではありません、私は確かに – astraujums
...と仮定します!修正済み... –
initializer_listから 'A'を作成し、' T'から 'P'を作成するのはまったく一致するはずなので、あいまいさがあります。私が説明できないことは、コンパイラが不平を言うために別のものを選ぶ理由です。 –