如何使用enable_if根据类的模板参数启用成员函数

时间:2010-11-11 20:00:24

标签: c++ templates metaprogramming sfinae

在代码中:

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

4 个答案:

答案 0 :(得分:13)

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

您需要

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

  • 将成员函数f移动到策略类中,并使用enable_if专门化类模板。

答案 1 :(得分:1)

您可以使用修改后的enable_if

修复代码
---
  - name: Check Application Versions
    hosts: kubernetes
    tasks:
       - name: Check K8S version.
         shell: kubectl --version
         register: k8s_version

       - local_action: template src=my_nodes.j2 dest=/tmp/test

使用示例:

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; };

答案 2 :(得分:0)

以下是它的工作原理(请注意,为方便起见,我将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";
    }
};

DEMO

关键部分是使用默认函数模板参数T_将模板参数带入立即上下文,该参数等于类模板参数T。有关详细信息,请参阅this question

答案 3 :(得分:-2)

enable_if需要一个元函数。要使用bool,您需要enable_if_c。我很惊讶你没有得到解释这个问题的错误。

你可以通过在其中声明一个'type'typedef来修复你的元函数。然后,您可以使用boost::enable_if<is_builtin<T>>::type