首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从专用模板方法调用非专用模板方法

从专用模板方法调用非专用模板方法
EN

Stack Overflow用户
提问于 2016-12-22 10:27:05
回答 2查看 533关注 0票数 2

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

在使用继承时,这很容易:

代码语言:javascript
复制
class SomeBaseClass {
  virtual void DoWork() { /* Do something */ }
};

class SomeClass : public SomeBaseClass {
  void DoWork() {
    // Do something first
    SomeBaseClass::DoWork();
  }
};

但在使用模板时有一点不同:

代码语言:javascript
复制
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函数中有很多非常好的代码,我不想重复。我的专用程序只有一个额外的步骤,它需要在使用特定类型时执行。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-22 13:13:01

你想错了。解决方案不是让您的类专门化,而是让您的功能专门化。这里我的意思是使用标记分派

也就是说,在类中声明两个名为privateDoWorkHelper帮助函数,其中一个函数重载了专门类型,另一个函数没有重载。

我们这样做的方法是将类型包装在基本上是空结构的“标记”中,然后将标记专门化为我们感兴趣的类型:

代码语言:javascript
复制
namespace SomeClassDetail{
template<class T>
struct specialized_tag : std::false_type{};

template<>
struct specialized_tag<int>: std::true_type{};
}

true_typefalse_type本质上就是false。它们很好,因为它们是类型而不是值(当我们模板时,我们都关心类型)

接下来,我们将使用前面提到的重载来声明类:

代码语言:javascript
复制
template <class T>
class SomeClass {
public:
  void DoWork();
  
  private:
  void DoWorkHelper(std::true_type);
  void DoWorkHelper(std::false_type);
};

这里的想法是,true_type的意思是“是的,这个函数是专门的版本!”

以下是定义的样子:

代码语言:javascript
复制
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)将只做它的事情。

下面是一个现场演示,演示了标记分派的实际操作

票数 1
EN

Stack Overflow用户

发布于 2016-12-22 10:40:50

类似于这里,您可以间接地这样做:

代码语言:javascript
复制
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
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41280944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档