我可以从专门的模板中调用非专业化的模板方法吗?
使用继承时这很容易:
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函数中有很多非常好的代码,我讨厌复制。我的专业人员只需要在使用特定类型时执行额外的步骤。
答案 0 :(得分:2)
与here类似,您可以间接地这样做:
template <class T>
class SomeClassCommonImpl {
void DoWork();
};
template<class T>
void SomeClassCommonImpl<T>::DoWork() { /* Do something */}
template <class T>
class SomeClass: public SomeClassCommonImpl<T> {
// use the default implementation
};
template <>
class SomeClass<int>: public SomeClassCommonImpl<int> {
void DoWork();
};
template<>
void SomeClass<int>::DoWork() {
// Do something first
SomeClassCommonImpl<int>::DoWork<>(); // Call the common method
}
答案 1 :(得分:1)
你以错误的方式思考这个问题。 解决方案不是让你的课程专业化,而是让你的职能专业化。我的意思是使用标签发送
也就是说,在名为private
的类中声明两个DoWorkHelper
辅助函数,其中一个函数为特殊类型重载,另一个不重载。
我们这样做的方法是将我们的类型包装在&#39;标签中。这基本上是一个空结构,然后专门为我们感兴趣的类型标记:
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
表示&#34;是的,此功能适用于专业版!&#34;
这里的定义是什么样的:
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
),将只是做它的事情。