2

最初に enable_if を使用します。以下に記述したコードはコンパイルされませんが、論理的には正しいように見えますが、現在の enable_if 実装ではサポートされません。

  1 
  2 #include <iostream>
  3 using namespace std;
  4 
  5 template<int N>
  6 struct S{
  7                 template<class T>
  8                 typename enable_if<N==1,T>::type
  9                 f(T t) {return 1;};
 10 
 11                 template<class T>
 12                 T
 13                 f(T t) {return 0;};
 14 };
 15 
 16 int main() {
 17     S<1> s1;
 18     S<2> s2;
 19     cout << s1.f(99) <<" "<< s2.f(99) << endl;
 20     return 0;
 21 }

エラーメッセージは正確で、問題は正確に指摘されています。

enable_if.cc19:20: error: call of overloaded ‘f(int)’ is ambiguous
enable_if.cc:9:3: error: no type named ‘type’ in   
                         ‘struct std::enable_if<false, int>’

これは、明確に定義されていない設計の問題にすぎないようで、簡単に修正できます。それに対処するために、部分的に特化したクラス テンプレートを記述できます。

#include <iostream>
using namespace std;

template<int N> struct S{
        template<class T>
        T
        f(T t) {return 0;};
};
template<> struct S<1>{
        template<class T>
        T
        f(T t) {return 1;};
};
int main() {
    S<1> s1;
    S<2> s2;
    cout << s1.f(99) <<" "<< s2.f(99) << endl;
    return 0;
}

しかし、クレンジングと利便性のために、enable_if テンプレートを拡張して、最初は間違ったコードによって促されたそのような新機能をサポートするにはどうすればよいでしょうか?

  • fをs1呼び出すと、例で 1 を返す、より特殊化されたものを使用できます。
  • fをs2呼び出すと、0 を返す一般的なものが使用され、最初の呼び出しでも失敗します。
4

4 に答える 4

0

std::enable_if関数のオーバーロードを選択するためのツールにすぎません。これは、 boostからの純粋なライブラリ ソリューションとして実装されます。適切なオーバーロードを選択するためのルールは簡単ではないと思います。ただし、特定のケースでこれを変更するよう求めると、enable_if複雑になります。したがって、部分的な特殊化と選言で作業するのが最善ですenable_if

于 2013-06-12T09:00:32.007 に答える