对于共享公共基类的类的以下代码中的方法doIt()
,我非常感谢,如下所示
#include <iostream>
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>
struct BarBase {};
struct Bar: BarBase {};
struct FooBase {};
struct Foo: FooBase {};
template <typename T>
struct Task
{
// I'd like to specialize this method for classes with a common base class
void doIt();
};
// my attempt (does not compile)
template <typename T>
typename boost::enable_if<boost::is_base_of<FooBase, T> >::value
doIt() {
std::cout << "Type is derived from FooBase\n";
}
int main()
{
Task<Foo> f;
f.doIt();
}
答案 0 :(得分:1)
您无法专门化模板类成员。你可以专门化一个类,每个专门化都是一个完整的独立类,它不会从非专用模板中继承任何内容(它可能有也可能没有非专用类的全部或部分成员)。
您还可以做的是在模板类中使用模板成员函数,并将其专门化。所以你可以这样做:
template <typename T>
struct Task
{
void doIt() { doItPriv<T>(); }
private:
template<typename T1>
void doItPriv();
};
然后专门化doItPriv
。
答案 1 :(得分:0)
根据this回答,
SFINAE仅在模板的参数推断中替换时才有效 论证使构造变得不合理。
这就是为什么你不能这样做的原因:
template <typename T>
struct Task
{
typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt() {
std::cout << "Type is derived from FooBase\n";
}
typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt()
{
}
};
此处doIt()
不是模板,因此没有任何扣除。
但是你可以做到以下几点:
template <typename T1>
struct Task
{
template <typename T>
typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt_() {
std::cout << "Type is derived from FooBase\n";
}
template <typename T>
typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt_()
{
}
void doIt()
{
doIt_<T1>();
}
};