我可以从专用方法中调用非专用模板方法吗?
使用继承时,这很容易:
class SomeBaseClass {
virtual void DoWork() { /* Do something */ }
};
class SomeClass : public SomeBaseClass {
void DoWork() {
// Do something first
SomeBaseClass::DoWork();
}
};
但是使用模板时有些不同:
template <class T>
class SomeClass {
void DoWork();
};
template<class T>
void SomeClass<T>::DoWork() { /* Do something */}
template<>
void SomeClass<int>::DoWork() {
// Do something first
DoWork<>(); // Call method from line 8
}
我的通用DoWork函数中有很多我非常想重复的非常好的代码。我的专门人员只是在使用特定类型时需要执行的额外步骤。
最佳答案
您正在以错误的方式思考。
解决方案不是让您的类专门化,而是让您的功能专门化。我的意思是使用标签分发
也就是说,在名为private
的类中声明两个DoWorkHelper
帮助器函数,其中一个对于特殊类型已重载,而另一个则没有。
我们这样做的方法是将类型包装在一个基本上是空结构的“标签”中,然后针对感兴趣的类型专门设置标签:
namespace SomeClassDetail{
template<class T>
struct specialized_tag : std::false_type{};
template<>
struct specialized_tag<int>: std::true_type{};
}
true_type
和false_type
本质上是wrappers for boolean true
and false
。它们很不错,因为它们是类型而不是值(并且当我们模版化时,我们关心所有类型)接下来,我们将使用上述重载声明我们的类:
template <class T>
class SomeClass {
public:
void DoWork();
private:
void DoWorkHelper(std::true_type);
void DoWorkHelper(std::false_type);
};
这里的想法是true_type
的意思是“是的,此功能适用于专业版本!”定义如下所示:
template<class T>
void SomeClass<T>::DoWork()
{
DoWorkHelper(typename SomeClassDetail::specialized_tag<T>::type{});
}
template<class T>
void SomeClass<T>::DoWorkHelper(std::true_type)
{
std::cout << "Specialized DoWork\n";
DoWorkHelper(std::false_type());
}
template<class T>
void SomeClass<T>::DoWorkHelper(std::false_type)
{
std::cout << "Unspecialized DoWork\n";
}
而已。专用版本将执行其操作,然后调用非专用版本,而非专用版本(对于所有其他T
)将仅执行其操作。Here's a live demo that demonstrates tag dispatch in action