我可以从专用模板方法中调用非专用模板方法吗?
在使用继承时,这很容易:
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函数中有很多非常好的代码,我不想重复。我的专用程序只有一个额外的步骤,它需要在使用特定类型时执行。
发布于 2016-12-22 13:13:01
你想错了。解决方案不是让您的类专门化,而是让您的功能专门化。这里我的意思是使用标记分派
也就是说,在类中声明两个名为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本质上就是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)将只做它的事情。
下面是一个现场演示,演示了标记分派的实际操作
发布于 2016-12-22 10:40:50
类似于这里,您可以间接地这样做:
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
}https://stackoverflow.com/questions/41280944
复制相似问题