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_if与std::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_if和std::is_base_of(声明<type_traits>)都是C++ 2011中的新功能.如果需要使用C++ 2003编译器进行编译,可以使用Boost中的实现(需要将命名空间更改为boost包含"boost/utility.hpp"而"boost/enable_if.hpp"不是相应的标准头文件).或者,如果您不能使用Boost,则可以非常轻松地实现这两个类模板.
我将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_type或std::false_type取决于的值T。还要注意,std::true_type和std::false_type仅仅是typedef,定义为:
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
Run Code Online (Sandbox Code Playgroud)