enable_if:テンプレートベースのテンプレートメソッドのケースは数回継承されました
質問
テンプレートメソッドを備えたテンプレートベースクラスがある場合:
template <typename T>
class S
{
public:
template <typename U>
void f(U p, typename enable_if<is_same<T, U> >::type*dummy = 0)
{
std::cout << p << std::endl;
}
};
例として、私は方法を簡素化します:t == uの場合にのみ「存在する必要があります」
Aがこのクラスの場合:
class A : public S<int> {};
それから私は私が望むものを持っています:
int i = 1;
A a;
a.f(i);
コンパイル、しかし
double d = 2.0;
a.f(d);
コンパイルしない:エラー:「a :: f(double&)」への呼び出しのマッチング関数は予想される動作です。
ここから継承しましょう S<double>
また :
class A : public S<int>, public S<double> {};
次のコードはコンパイルされません。
int i = 1;
A a;
a.f(i);
error: request for member ‘f’ is ambiguous error: candidates are: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = double] error: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = int]
曖昧さはないと思っていました: f<int>
のみ存在します S<int>
コンパイラエラーでは、このコードがコンパイルされているときにTがわかっているが、u(u = u)ではないことがわかります。
説明や「回避策」はありますか?
解決
これを試して:
a.S<int>::f(i);
...または、関数をに注入します A
, 、例:
class A : public S<int>, public S<double>
{
public:
using S<int>::f;
using S<double>::f;
};
他のヒント
あなたは正しいですそれはsにしか存在しませんが、2回です。各タイプの1回、INTとダブル。したがって、あなたの場合、呼び出す関数を正確に指定する必要があります。 NIMの解決策はそのように機能します。
他の人は良い回避策を与えましたが、私はあなたが持っていた他の質問に答えたいと思います
曖昧さはないと思っていました:
f<int>
のみ存在しますS<int>
.
あなたが言った a.f(i)
したがって、最初に名前を探す必要があります f
の A
. 。 2つを見つけます f
s。の S<int>
と S<double>
. 。名前の検索時間では、後で選択したことがあることはまだわかりません S<int>::f
なぜなら、勝者として S<double>::f
Sfinaeによって捨てられます。名前のルックアップと過負荷解像度とテンプレート引数の控除の明確な分離は、そのような混合を許可しません。