具有指针模板参数的模板 class 特化
Specialization of template class with pointer template argument
我想为几个指向不同对象的指针专门化一个模板 class。对于普通指针,这按预期工作:
struct Base{} b;
template<Base* B> struct Test{};
template<> struct Test<&b>{};
但不适用于指向 Derived
对象的指针:
struct Derived : Base{} d;
template<> struct Test<&d>{};
coliru 编译器(我认为是 gcc 5.2
)显示以下错误:
main.cpp:14:26: error: could not convert template argument '& d' to 'Base*'
template<> struct Test<&d>{};
我不知道,为什么不允许这样做,想知道是否有解决该问题的方法...
Here 是对 coliru 中代码的 link。
如果你愿意稍微改变一下模板参数是可以的:
struct Base {} b;
struct Derived : Base {} d;
struct A {} a;
template <class T, T *B,
class = std::enable_if_t<std::is_base_of<Base, T>::value>>
struct Test {};
template <> struct Test<Base, &b> {}; // OK
template <> struct Test<Derived, &d> {}; // OK
template <> struct Test<A, &a> {}; // compile error
您可以为所有类型(如果相关)定义通用模板,并为指针类型定义部分特化:
template <typename T>
struct MyTest { // generic implementation for all types
MyTest() { // here I make it unrelevant
static_assert(is_pointer<T>::value , "this class must be used with a pointer");
}
};
template <typename T>
struct MyTest<T*> { // partial specialisation for pointer types
MyTest() {
cout <<"generic implementation"<<endl;
}
};
您可以根据需要定义更多专业:
struct Base {};
struct Derived : Base {};
template <>
struct MyTest<Base*> { // specialisation for Base
MyTest() {
cout <<"specialized implementation for Base"<<endl;
}
};
template <>
struct MyTest<Derived*> { // specialisation for Derived
MyTest() {
cout <<"specialized implementation for Derived"<<endl;
}
};
在这里你可以如何使用它:
MyTest<Base> mt1; //<== faills because Base is not a poiner
MyTest<int*> mt0; // generic template
MyTest<Base*> mt2; // Base specialisation
MyTest<Derived*> mt3; // derived specialisation
这里是online demo。
我想为几个指向不同对象的指针专门化一个模板 class。对于普通指针,这按预期工作:
struct Base{} b;
template<Base* B> struct Test{};
template<> struct Test<&b>{};
但不适用于指向 Derived
对象的指针:
struct Derived : Base{} d;
template<> struct Test<&d>{};
coliru 编译器(我认为是 gcc 5.2
)显示以下错误:
main.cpp:14:26: error: could not convert template argument '& d' to 'Base*'
template<> struct Test<&d>{};
我不知道,为什么不允许这样做,想知道是否有解决该问题的方法...
Here 是对 coliru 中代码的 link。
如果你愿意稍微改变一下模板参数是可以的:
struct Base {} b;
struct Derived : Base {} d;
struct A {} a;
template <class T, T *B,
class = std::enable_if_t<std::is_base_of<Base, T>::value>>
struct Test {};
template <> struct Test<Base, &b> {}; // OK
template <> struct Test<Derived, &d> {}; // OK
template <> struct Test<A, &a> {}; // compile error
您可以为所有类型(如果相关)定义通用模板,并为指针类型定义部分特化:
template <typename T>
struct MyTest { // generic implementation for all types
MyTest() { // here I make it unrelevant
static_assert(is_pointer<T>::value , "this class must be used with a pointer");
}
};
template <typename T>
struct MyTest<T*> { // partial specialisation for pointer types
MyTest() {
cout <<"generic implementation"<<endl;
}
};
您可以根据需要定义更多专业:
struct Base {};
struct Derived : Base {};
template <>
struct MyTest<Base*> { // specialisation for Base
MyTest() {
cout <<"specialized implementation for Base"<<endl;
}
};
template <>
struct MyTest<Derived*> { // specialisation for Derived
MyTest() {
cout <<"specialized implementation for Derived"<<endl;
}
};
在这里你可以如何使用它:
MyTest<Base> mt1; //<== faills because Base is not a poiner
MyTest<int*> mt0; // generic template
MyTest<Base*> mt2; // Base specialisation
MyTest<Derived*> mt3; // derived specialisation
这里是online demo。