2

テンプレートメソッドを持つテンプレート基本クラスがある場合:

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>次に、 Aも継承しましょう。

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) は認識されていないことがわかります。

説明または「回避策」はありますか?

4

3 に答える 3

4

これを試して:

a.S<int>::f(i);

A...または代わりに、関数をに注入します。

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};
于 2011-10-20T14:53:36.043 に答える
0

他の人は良い回避策を与えました、しかし私はあなたが持っていた他の質問に答えたいです

あいまいさがないことを期待しました:にf<int>のみ存在しS<int>ます。

あなたが言っa.f(i)たので、最初にで名前を探す必要がfありますA。2つのを見つけfます。S<int>S<double>。_ 名前の検索時に、 SFINAEによって破棄されるS<int>::fため、後で勝者としてのみ選択できた可能性があることはまだわかりません。S<double>::f名前検索とオーバーロード解決、およびテンプレート引数の推定を明確に分離することで、このような混合は許可されません。

于 2011-10-23T02:01:44.690 に答える
0

あなたの言うとおり、S にしか存在しませんが、2 回存在します。タイプごとに 1 回、int および double。したがって、あなたの場合、呼び出す関数を正確に指定する必要があります。Nim のソリューションはそのように機能します。

于 2011-10-20T14:58:15.820 に答える