11

假设我有一个模板类:

template <typename T>
class foo {
  void do_someting(T obj) {
    // do something generic...
  }
};

我想专门化do_something,但在其中我想调用“正常”的do_something函数:

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  // and ALSO do something generic!
}

有没有办法在我的专业函数中引用 do_something 的正常版本?还是我只需要复制代码?

(我知道我可以重构 foo 以使我不会遇到这个确切的问题,但是碰巧我不能真正修改“真正的” foo,因为它是高度共享的代码。)

4

3 回答 3

7

不,您的专业化是 MyObj 类型参数存在的唯一定义。但是,考虑以这种方式修改 foo 模板,这将对模板的当前用户透明:

template<typename T>
class foo {
  void prelude(T &obj){ // choose a better name
    /* do nothing */
  }
  void do_something(T obj){
    prelude(obj);
    // do something generic...
  }
};

然后为前奏定义一个专业化:

template<>
void foo<MyObj>::prelude(MyObj &obj){
  // do something specific
}

这在结构上与私有虚拟成员的主要用例有些相似。(有点。不是真的。但这就是我在这个答案中的灵感。)

于 2010-11-04T17:21:11.390 回答
1

您可能还会考虑不是 MyObj 的类型,但会隐式转换为它,但最好的方法是重构并可能提取通用泛型的东西。

#include <iostream>
#include <boost/ref.hpp>
typedef int MyObj;


template <typename T>
struct foo {
  void do_something(T obj) {
    // do something generic...
    std::cout << "generic " << obj << '\n';
  }
};

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  std::cout << "special " << obj << '\n';
  // and ALSO do something generic!
  foo<boost::reference_wrapper<MyObj> >().do_something(boost::ref(obj));
}

int main()
{
    foo<int> f;
    f.do_something(10);
}
于 2010-11-04T17:33:07.703 回答
0

是的,这实际上非常简单。您只需让函数的主要通用版本作为“实现”通用函数的传递,该函数不会部分专用,然后您可以根据需要从初始函数的专用版本调用它。

template <typename T>
class foo 
{
  void do_something(T obj) 
  {
     do_something_impl(obj);
  }

  void do_something_impl(T obj)
  {
    // do something generic...
  }
};

现在专业化可以毫无问题地调用通用版本:

template<>
void foo<MyObj>::do_something(MyObj obj) 
{
  // do something specific...
  do_something_impl(obj); //The generic part
}

我认为这比史蒂夫 M. 的回答更接近你的初衷,这也是我在面对这个问题时所做的。

于 2012-06-08T14:01:08.823 回答