考虑以下示例程序:
#include <iostream>
template<typename T>
struct Dispatch
{
static void send(T&) { std::cout << "unknown\n"; }
};
struct Processor
{
template<typename T>
void process(T&& t) { Dispatch<T>::send(t); }
};
template<typename T>
struct Base
{};
template<typename T>
struct Dispatch<Base<T>>
{
static void send(Base<T>&) { std::cout << "base\n"; }
};
struct Deriv : Base<int>
{};
int main()
{
Processor p;
p.process(Base<int>{}); // prints "base"
p.process(Deriv{}); // prints "unknown"
return 0;
}
使用Processor::process()
实例(Deriv
子类)调用Base
时,我希望Dispatcher()
专门用于Base
类模板地选择。
但是,在上面的示例中,会发生以下情况:
Base<T>
个实例传递给process()
,调用Base<T>
专业化Deriv
实例传递给process()
调用主类模板问题:
Base<T>
不是Deriv
比主要类模板更好的专业化?Base<T>
子类时是否有通用的方法来调用Base<T>
专门化?答案 0 :(得分:4)
使用SFINAE,您可以:
// Traits to detect inheritance:
template <typename T> std::true_type derive_from_base_impl(Base<T>*);
std::false_type derive_from_base_impl(...);
template <typename T>
using derive_from_base_t = decltype(derive_from_base_impl(std::declval<T*>()));
然后进行一些更改
template<typename T, typename Enabler = void>
struct Dispatch
{
static void send(T&) { std::cout << "unknown\n"; }
};
template<typename T>
struct Dispatch<T, std::enable_if_t<derive_from_base_t<T>::value>>
{
static void send(T&) { std::cout << "base\n"; }
};
答案 1 :(得分:3)
模板专业化适用于字面上相同的类型。如果您使用Base
专用模板,则此专精化不适用于Derived
。
解决此问题的一种方法是使用您为Base
派生的类型启用的部分特化。