【问题标题】:Function templates: Different specializations with type traits函数模板:具有类型特征的不同特化
【发布时间】:2012-08-28 07:39:00
【问题描述】:

考虑到类模板,可以使用类型特征和虚拟启动器模板参数为某些类型的组提供模板特化。我已经asked that earlier了。

现在,对于函数模板,我需要同样的东西:即,我有一个模板函数,并且想要对一组类型进行专门化,例如,作为类 X 子类型的所有类型。我可以用这样的类型特征来表达这一点:

std::enable_if<std::is_base_of<X, T>::value>::type

我想过这样做:

template <typename T, typename ENABLE = void>
void foo(){
    //Do something
}

template <typename T>
void foo<T,std::enable_if<std::is_base_of<A, T>::value>::type>(){
    //Do something different
}

但是,这不起作用,因为函数模板不允许部分特化。那么该怎么做呢?也许是类型特征作为类型的默认参数?但是代码看起来怎么样呢?

【问题讨论】:

  • 你实际上用这个做什么?更喜欢重载函数而不是专门化它们的模板。希望您的预期用途允许这样做。

标签: c++ templates typetraits function-templates


【解决方案1】:

重载:

void foo_impl(T, std::false_type);

void foo_impl(T, std::true_type);

foo(T t) { foo_impl(t, std::is_base_of<A, T>()); }

【讨论】:

    【解决方案2】:

    最接近您所要求的是返回类型上的enable_if

    template<typename T> typename std::enable_if<std::is_same<T, int>::value>::type foo();
    template<typename T> typename std::enable_if<std::is_same<T, char>::value>::type foo();
    

    但是,分派到辅助函数或类可能更具可读性和效率。

    辅助函数:

    template<typename T> void foo_helper(std::true_type);
    template<typename T> void foo_helper(std::false_type);
    template<typename T> void foo() { foo_helper(std::is_same<T, int>()); }
    

    助手类:

    template<typename T, bool = std::is_same<T, int>::value> struct foo_helper {};
    template<typename T> struct foo_helper<T, true> { static void foo(); };
    template<typename T> struct foo_helper<T, false> { static void foo(); };
    template<typename T> void foo() { foo_helper<T>::foo(); }
    

    【讨论】:

    • 好吧,通过使用返回类型,我什至可以省略默认参数
    • @gexicide 但是,您必须对每个函数定义进行专门化,因此您无法像对类模板那样拥有“包罗万象”的定义。
    【解决方案3】:

    在类模板中进行实际实现(部分特化等),并编写一个小的包装模板函数,它只在类模板中调用一个静态函数。

    【讨论】:

      【解决方案4】:

      尝试了一些方法,最后我自己想出了正确的语法 - 抱歉问了。我不知道 enable_if 有第二个参数。通过使用这个参数和一个默认值,这是可能的。

      这就是答案

      template<typename T>
      void foo(typename std::enable_if<std::is_base_of<A, T>::value,int>::type ENABLER = 0){
          std::cout << "T is a subclass of A!";
      }
      
      template<typename T>
      void foo(typename std::enable_if<!std::is_base_of<A, T>::value,int>::type ENABLER = 0){
          std::cout << "T is NOT a subclass of A";
      }
      

      【讨论】:

      • 再一次,你输了一般情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多