12

コード内:

template<class T>
struct is_builtin
{
    enum {value = 0};
};

template<>
struct is_builtin<char>
{
    enum {value = 1};
};

template<>
struct is_builtin<int>
{
    enum {value = 1};
};

template<>
struct is_builtin<double>
{
    enum {value = 1};
};

template<class T>
struct My
{
    typename enable_if<is_builtin<T>::value,void>::type f(T arg)
    {
        std::cout << "Built-in as a param.\n";
    }


    typename enable_if<!is_builtin<T>::value,void>::type f(T arg)
    {
        std::cout << "Non - built-in as a param.\n";
    }
};

struct A
{
};

int main()
{
    A a;
    My<int> m;
    My<A> ma;
    m.f(1);
    ma.f(a);
    return 0;
}

エラーが発生しました:

error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test,_Type>'    

明らかに、私は使用方法を理解していませんenable_if。私が考えていたのは、コンパイル時に一連のメンバー関数から1つまたは2番目の1つのメンバー関数を有効にできるが、機能しないということでした。誰かがそれを正しく行う方法を私に説明してもらえますか?
編集
私が本当に理解できないのは、なぜtypedefそれらのdefの1つに存在しないのかということです。コンパイラはそれを見つけることができず、コンパイルしません。

4

4 に答える 4

14

クラステンプレートパラメータを使用して、メンバー関数のSFINAEを取得することはできません。

あなたはどちらかをする必要があります

  • 代わりに、メンバー関数をメンバー関数テンプレートにenable_ifして、メンバー関数テンプレートのテンプレートパラメーターで使用するか、

  • メンバー関数fをポリシークラスに移動し、を使用してクラステンプレートを特殊化しenable_ifます。

于 2010-11-11T20:07:48.910 に答える
2

これがどのように機能するかです(便宜上、私はあなたのis_builtin特性をstd::is_arithmeticC ++ 11のものに置き換え、さらに使用したことに注意してください、しかしそれはとにかく機能します):

template<class T>
struct My
{
    template<typename T_ = T, std::enable_if_t<std::is_arithmetic<T_>::value>* = nullptr>
    void f(T_ arg)
    {
        std::cout << "Built-in as a param.\n";
    }

    template<typename T_ = T, std::enable_if_t<!std::is_arithmetic<T_>::value>* = nullptr>
    void f(T_ arg)
    {
        std::cout << "Non - built-in as a param.\n";
    }
};

デモ

重要な部分は、クラステンプレートパラメータと等しいデフォルトの関数テンプレートパラメータを使用して、テンプレートパラメータを直接のコンテキストに取り込むことです。詳細については、この質問を参照してください。T_T

于 2016-02-15T22:28:24.380 に答える
0

変更されたenable_ifを使用してコードを修正できます

template < typename T >
struct __Conflict {};

template <bool B, class T = void>
struct __enable_if { typedef __Conflict<T> type; };

template <class T>
struct __enable_if<true, T> { typedef T type; };

使用例:

template <typename T>
class Lazy
{
public:
    void _ctor(bool b);
    void _ctor(typename __enable_if<!std::is_same<T, bool>::value, T>::type);
};

template <typename T>
void Lazy<T>::_ctor(bool b)
{
    std::cout << "bool " << b << std::endl;
};

template <typename T>
void Lazy<T>::_ctor(typename __enable_if<!std::is_same<T, bool>::value, T>::type t)
{
    std::cout << "T " << t << std::endl;
};

int main(int argc, char **argv)
{
    Lazy<int> i;
    i._ctor(10);
    i._ctor(true);

    Lazy<bool> b;
    b._ctor(true);

    return 0;
}
于 2017-07-11T13:39:49.957 に答える
-2

enable_ifはメタ関数を期待します。boolを使用するには、enable_if_cが必要です。その問題を説明するエラーが発生していないことに驚いています。

メタ関数は、それ自体である「type」typedefを内部で宣言することで修正できます。その後、あなたは使用することができますboost::enable_if<is_builtin<T>>::type

于 2010-11-11T20:35:40.223 に答える