所有子类的c ++模板特化

Abh*_*and 9 c++ templates template-specialization

我需要创建一个这样的模板函数:

template<typename T>
void foo(T a)
{
   if (T is a subclass of class Bar)
      do this
   else
      do something else
}
Run Code Online (Sandbox Code Playgroud)

我也可以想象使用模板特化来做它...但我从未见过超类的所有子类的模板特化.我不想为每个子类重复专门化代码

Die*_*ühl 14

你可以做你想做的事,但不能做你想做的事!您可以std::enable_ifstd::is_base_of:

#include <iostream>
#include <utility>
#include <type_traits>

struct Bar { virtual ~Bar() {} };
struct Foo: Bar {};
struct Faz {};

template <typename T>
typename std::enable_if<std::is_base_of<Bar, T>::value>::type
foo(char const* type, T) {
    std::cout << type << " is derived from Bar\n";
}
template <typename T>
typename std::enable_if<!std::is_base_of<Bar, T>::value>::type
foo(char const* type, T) {
    std::cout << type << " is NOT derived from Bar\n";
}

int main()
{
    foo("Foo", Foo());
    foo("Faz", Faz());
}
Run Code Online (Sandbox Code Playgroud)

由于这些东西得到了更广泛的传播,人们已经讨论过某种东西,static if但到目前为止它还没有出现.

两者std::enable_ifstd::is_base_of(声明<type_traits>)都是C++ 2011中的新功能.如果需要使用C++ 2003编译器进行编译,可以使用Boost中的实现(需要将命名空间更改为boost包含"boost/utility.hpp""boost/enable_if.hpp"不是相应的标准头文件).或者,如果您不能使用Boost,则可以非常轻松地实现这两个类模板.


Naw*_*waz 5

我将std::is_base_of与本地类一起使用:

#include <type_traits>  //you must include this: C++11 solution!

template<typename T>
void foo(T a)
{
   struct local
   {
        static void do_work(T & a, std::true_type const &)
        {
            //T is derived from Bar
        }
        static void do_work(T & a, std::false_type const &)
        {
            //T is not derived from Bar
        }
   };

   local::do_work(a, std::is_base_of<Bar,T>());
}
Run Code Online (Sandbox Code Playgroud)

请注意,是std::is_base_of从派生的std::integral_constant,因此前一种类型的对象可以隐式转换为后一种类型的对象,这意味着std::is_base_of<Bar,T>()将转换为std::true_typestd::false_type取决于的值T。还要注意,std::true_typestd::false_type仅仅是typedef,定义为:

typedef integral_constant<bool, true>  true_type;
typedef integral_constant<bool, false> false_type;
Run Code Online (Sandbox Code Playgroud)