Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中专门化函数时调用该函数的非专门化版本+;?_C++_Templates_Template Specialization - Fatal编程技术网

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

C++ 在C+中专门化函数时调用该函数的非专门化版本+;?,c++,templates,template-specialization,C++,Templates,Template Specialization,假设我有一个模板类: template <typename T> class foo { void do_someting(T obj) { // do something generic... } }; 模板 福班{ 无效执行某些操作(T obj){ //做些普通的事情。。。 } }; 我想专门化do_something,但在其中我想调用“普通”do_something函数: template<> void foo<MyObj>::do_

假设我有一个模板类:

template <typename T>
class foo {
  void do_someting(T obj) {
    // do something generic...
  }
};
模板
福班{
无效执行某些操作(T obj){
//做些普通的事情。。。
}
};
我想专门化do_something,但在其中我想调用“普通”do_something函数:

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  // and ALSO do something generic!
}
模板
void foo::做点什么(MyObj obj){
//做一些具体的事情。。。
//并且做一些普通的事情!
}
在我的专业功能中,有没有办法引用do_something的正常版本?还是我只需要复制代码


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

不。您的专门化是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...
  }
};
模板
福班{
无效前奏曲(T&obj){//选择一个更好的名字
/*无所事事*/
}
无效做某事(目标){
前奏曲;
//做些普通的事情。。。
}
};
然后定义前奏曲的特殊化:

template<>
void foo<MyObj>::prelude(MyObj &obj){
  // do something specific
}
模板
福娃:前奏曲(MyObj&obj){
//做一些具体的事情
}

这在结构上有点类似于。(不是这样。但这正是启发我这个答案的原因)。

你也可以考虑一个不是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);
}
#包括
#包括
typedef int MyObj;
模板
结构foo{
无效做某事(目标){
//做些普通的事情。。。

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

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

  void do_something_impl(T obj)
  {
    // do something generic...
  }
};
模板
福班
{
无效做某事(目标)
{
做一些简单的事情(obj);
}
无效执行某些内容(目标)
{
//做些普通的事情。。。
}
};
现在,专业化可以毫无问题地调用通用版本:

template<>
void foo<MyObj>::do_something(MyObj obj) 
{
  // do something specific...
  do_something_impl(obj); //The generic part
}
模板
void foo::做点什么(MyObj obj)
{
//做一些具体的事情。。。
do_something_impl(obj);//通用部分
}

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

没有“正常”的问题类型
MyObj
do\u something
版本-模板专门化的整个效果是用专门化中定义的类/函数替换从基模板获得的实例化。可能是正确的重复,但编译器知道foo::do\u something中的代码,这是错误的没有理由不让我以某种方式引用它。我完全愿意相信这个语言功能根本不存在——这就是我想找到的。@Steve Townsend——这是一个不同的问题。这是问你如何拥有一个包含一些专用函数和一些非专用函数的类。“没有理由不让我参考它"-如果模板是以一种完全不同的方式定义的,那就没有理由了。事实上,
foo
是一个类,它有一个
dou\u something
函数,该函数是由专门化定义的。如果基本模板
foo
是用参数
MyObj
实例化的,结果将是另一个类,al所以
foo
,这是不允许的,这就是障碍。我想如果该语言以某种方式允许您将基础模板实例化为不同的名称,您可能会没事,但没有这样的运气。这看起来确实像是Sutter的NVI的模板世界类比!