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. 我在想的是,我可以在编译期间从一组成员函数中启用一个或第二个成员函数,但它不起作用。谁能向我解释如何正确地做到这一点?
已编辑
我真正无法理解的是为什么typedef其中一个 def 中没有。编译器找不到它,它不会编译它。

4

4 回答 4

14

您不能使用类模板参数来获取成员函数的 SFINAE。

你要么需要

  • 使成员函数成为成员函数模板,并enable_if在成员函数模板的模板参数上使用或

  • 将成员函数移动f到策略类中,并使用enable_if.

于 2010-11-11T20:07:48.910 回答
2

以下是它的工作原理(请注意,为方便起见,我用 C++11 替换了你的is_builtin特性std::is_arithmetic并使用了更多的 C++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 需要一个元函数。要使用布尔值,您需要 enable_if_c。我很惊讶你没有得到解释那个问题的错误。

您可以通过在内部声明一个简单的“类型”typedef 来修复您的元函数。然后你可以使用boost::enable_if<is_builtin<T>>::type

于 2010-11-11T20:35:40.223 回答