2010-11-04 54 views
11

说我有一个模板类:在C++中专门调用函数的非专用版本?

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

对于MyObj类型,没有“do_something”的“正常”版本 - 模板专门化的全部效果是*替换*您将从基本模板获得的实例化,并且使用类/函数在专业化中定义。 – 2010-11-04 17:11:21

+0

可能的重复[如何获得一个专门的模板来使用非特化版本的成员函数?](http://stackoverflow.com/questions/347096/how-can-i-get-a-specialized-template-使用非特定版本的成员) – 2010-11-04 17:12:37

+1

对,但编译器知道foo中的代码 :: do_something,没有理由为什么它不能让我以某种方式引用它。我完全愿意相信这种语言功能根本不存在,但是---这正是我想要发现的。 – 2010-11-04 17:13:41

回答

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 
} 

这是有点类似结构为main use case for private virtual members。 (排序,不是真的,但这是什么启发我在这个答案。)

+0

这看起来像Sutter的NVI的模板世界比喻! – 2017-08-02 14:57:36

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); 
} 
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.的答案,是我做什么,当面对这个问题。