我可以从专用方法中调用非专用模板方法吗?

使用继承时,这很容易:

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_typefalse_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

09-04 17:50