代码之家  ›  专栏  ›  技术社区  ›  Jacob B

在C++中专门化函数时调用函数的非专业化版本?

  •  11
  • Jacob B  · 技术社区  · 15 年前

    假设我有一个模板类:

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

    我想专门做些什么,但在里面我想调用“普通”的做什么函数:

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

    有没有办法在我的专业功能中引用dou-something的正常版本?或者我只需要复制代码?

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

    3 回复  |  直到 15 年前
        1
  •  7
  •   Steve M    15 年前

    不,你的专业化是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
    }
    

    这在结构上与 main use case for private virtual members

        2
  •  1
  •   UncleBens    15 年前

    您还可以考虑一个不是MyObj的类型,但它隐式地转换为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);
    }
    
        3
  •  0
  •   Matt Phillips    14 年前

    是的,这其实很简单。只需让函数的主泛型版本作为传递给“implementation”泛型函数

    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
    }