从专门的模板方法调用unspecialized模板方法

时间:2016-12-22 10:27:06

标签: c++ templates

我可以从专门的模板中调用非专业化的模板方法吗?

使用继承时这很容易:

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函数中有很多非常好的代码,我讨厌复制。我的专业人员只需要在使用特定类型时执行额外的步骤。

2 个答案:

答案 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_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表示&#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),将只是做它的事情。

Here's a live demo that demonstrates tag dispatch in action