C++ 使用以基类为参数的模板
我想定义一个模板类,为不同的类型专门化一些方法C++ 使用以基类为参数的模板,c++,templates,sfinae,C++,Templates,Sfinae,我想定义一个模板类,为不同的类型专门化一些方法 template <typename T> class Handler { public: void method1() { method2(); } protected: void method2(); } 模板 类处理程序{ 公众: void method1(){method2();} 受保护的: void方法2(); } 然后在实现文件中: template <> Handler<int>
template <typename T>
class Handler {
public:
void method1() { method2(); }
protected:
void method2();
}
模板
类处理程序{
公众:
void method1(){method2();}
受保护的:
void方法2();
}
然后在实现文件中:
template <> Handler<int>::method2() { doSomething(); }
template <> Handler<float>::method2() { doSomethingElse(); }
template <> Handler<ClassB>::method2() { doSomethingDifferent(); }
模板处理程序::method2(){doSomething();}
模板处理程序::method2(){doSomethingElse();}
模板处理程序::method2(){doSomethingDifferent();}
到目前为止,一切正常
现在我想定义一些从ClassB派生的新类,并在这些类的对象上使用模板专门化。当然,它会编译,但不会链接,因为缺少每个子类的专门化
是否有方法使用这些模板,例如使用SFINAE?首先:
template <class T,class=void>
class Handler
模板
类处理程序
然后使用SFINAE创建专门化:
template <class T>
class Handler<T,std::enable_if_t<test>>
namespace {
template<class T> struct Type { using type = T; }; // Or boost::type<T>
template<class T> struct TypeTag { using type = Type<T>; };
struct ClassB {};
template <typename T>
class Handler {
public:
void method1() {
method2(typename TypeTag<T>::type{}); // Call an overloaded function.
}
protected:
void method2(Type<int>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
void method2(Type<float>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
void method2(Type<ClassB>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
};
// Somewhere else.
struct ClassC : ClassB {};
template<> struct TypeTag<ClassC> { using type = Type<ClassB>; };
} // namespace
int main(int ac, char**) {
Handler<ClassB> b;
b.method1();
Handler<ClassC> c;
c.method1();
}
模板
类处理程序
现在,让该专门化在其主体中包含其实现,或者从实现类型(非模板)继承并在impl文件中实现
对于你的钱包来说,测试可能是你成功的基础
您的int impl现在需要添加一个,void
参数
您还可以使用traits类进行条件映射。我经常发现类型标记上的重载是专门化的一个很好的替代:
template <class T>
class Handler<T,std::enable_if_t<test>>
namespace {
template<class T> struct Type { using type = T; }; // Or boost::type<T>
template<class T> struct TypeTag { using type = Type<T>; };
struct ClassB {};
template <typename T>
class Handler {
public:
void method1() {
method2(typename TypeTag<T>::type{}); // Call an overloaded function.
}
protected:
void method2(Type<int>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
void method2(Type<float>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
void method2(Type<ClassB>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
};
// Somewhere else.
struct ClassC : ClassB {};
template<> struct TypeTag<ClassC> { using type = Type<ClassB>; };
} // namespace
int main(int ac, char**) {
Handler<ClassB> b;
b.method1();
Handler<ClassC> c;
c.method1();
}
名称空间{
模板结构类型{using Type=T;};//或boost::Type
模板结构类型标记{using type=type;};
结构类B{};
模板
类处理程序{
公众:
void method1(){
method2(typename-TypeTag::type{});//调用重载函数。
}
受保护的:
void method2(Type){std::printf(“%s\n”,uu PRETTY_FUNCTION_uuu)}
void method2(Type){std::printf(“%s\n”,uu PRETTY_FUNCTION_uuu)}
void method2(Type){std::printf(“%s\n”,uu PRETTY_FUNCTION_uuu)}
};
//在别的地方。
结构ClassC:ClassB{};
模板结构类型标记{using type=type;};
}//名称空间
int main(int ac,字符**){
处理程序b;
b、 方法1();
处理程序c;
c、 方法1();
}
产出:
void {anonymous}::Handler<T>::method2({anonymous}::Type<{anonymous}::ClassB>) [with T = {anonymous}::ClassB]
void {anonymous}::Handler<T>::method2({anonymous}::Type<{anonymous}::ClassB>) [with T = {anonymous}::ClassC]
void{anonymous}::Handler::method2({anonymous}::Type)[with T={anonymous}::ClassB]
void{anonymous}::Handler::method2({anonymous}::Type)[with T={anonymous}::ClassC]
您可以在头文件中包含模板代码-这可能不是您想要的,因为模板专门化在概念上不同于继承。如果模板中的成员函数未定义,则不能期望它像这样工作。你在找什么?如果没有,请更清楚地说明您试图实现的目标。我将尝试一下。这看起来像是使用附加间接级别的经典解决方案。@GB是的,您的观察非常准确。另一种方法是将所有类型映射到几个特定类别TypeTag
将typeT
映射到categoryTypeTag::type
。专门化TypeTag
允许为任何类型定义类别。