enable_if:テンプレートベースのテンプレートメソッドのケースは数回継承されました

StackOverflow https://stackoverflow.com/questions/7837618

質問

テンプレートメソッドを備えたテンプレートベースクラスがある場合:

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) したがって、最初に名前を探す必要があります fA. 。 2つを見つけます fs。の S<int>S<double>. 。名前の検索時間では、後で選択したことがあることはまだわかりません S<int>::f なぜなら、勝者として S<double>::f Sfinaeによって捨てられます。名前のルックアップと過負荷解像度とテンプレート引数の控除の明確な分離は、そのような混合を許可しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top