模板通过const引用 [英] template pass by const reference

查看:164
本文介绍了模板通过const引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查看了几个类似的问题,但我还是很困惑。我试图找出如何显式地(不是通过编译器优化等)和C ++ 03兼容避免复制一个对象,当传递到一个专用模板功能。这里是我的测试代码:

  #include< iostream> 

using namespace std;

struct C
{
C(){cout< C()< endl; }
C(const C&){cout<< C(C)< endl; }
〜C(){cout<< 〜C()< endl; }
};

template< class T> void f(T){cout < f T << endl; }

//这显示了两种可能的方式,我不需要两个重载
//如果我这样做(2)函数不被调用,只有当我这样做(1)

模板<> void f(C c){cout < f C << endl; } //(1)

template<> void f(const C& c){cout< f< C&> << endl; } //(2)

int main()
{
C c;
f(c);
return 0;
}

(1)接受类型 C ,并进行复制。这里是输出:

  C()
C(C)
f&
〜C()
〜C()

专门用一个 const C& 参数(2)来避免这种情况,但这根本不工作(显然原因解释在这个问题)。



好吧,我可以传递指针,但这是一种丑陋。所以有一些窍门,可以允许这么做的好吗?



编辑:哦,可能是我不清楚。我已经有一个模板函数

  template< class T& void f(T){...} 

但现在我想专门化这个函数来接受常数&到另一个对象:

 模板< void f(const SpecificObject&){...} 

as

 模板<> void f(SpecificObject){...} 

基本上我想要做的这个专业化是使 SpecificObject 适应模板界面,如

  template< void f(SpecificObject obj){f(obj.Adapted()); } //调用模板版本

EDIT2:好的,我可以强制 const C& 专业化以这种方式调用:

  f< const C&> ); 

但是有办法让它像这样工作 f c)



EDIT3:如果有人最终会有类似的问题,我终于在另一个问题中找到了这个链接, a href =http://www.gotw.ca/publications/mill17.htm =nofollow> http://www.gotw.ca/publications/mill17.htm

$所以如果你不总是想接受一个const引用(这是合理的基类型[int,long,float等])。 ,你可以使用一点点提升魔法。

  #include< iostream> 
#include< boost / call_traits.hpp>

using namespace std;

struct C
{
C(){cout< C()< endl; }
C(const C&){cout<< C(C)< endl; }
// C& operator =(C const&){cout<< C = C< endl; return * this; }
〜C(){cout<< 〜C()< endl; }
};

template< class T> void foo(typename boost :: call_traits< T> :: param_type inst){cout< f T << endl; }
//用于调用类C
的特殊化模板<> void foo< C>(boost :: call_traits< C> :: param_type inst){cout< f C << endl; }

int main()
{
int i = 0;
foo< int>(i);
C c;
foo< C>(c);
return 0;
}


I've looked over a few similar questions, but I'm still confused. I'm trying to figure out how to explicitly (not by compiler optimization etc) and C++03-compatible avoid copying of an object when passing it to a specialized template function. Here is my test code:

#include <iostream>

using namespace std;

struct C
{
  C() { cout << "C()" << endl;  }
  C(const C&) { cout << "C(C)" << endl; }
  ~C() { cout << "~C()" << endl;  }
};

template<class T> void f(T) { cout << "f<T>" << endl; }

// This shows two possible ways, I don't need two overloads
// If I do it like (2) the function is not called, only if I do it like (1)

template<> void f(C c) { cout << "f<C>" << endl; } // (1)

template<> void f(const C& c) { cout << "f<C&>" << endl; } // (2)

int main()
{
    C c;
    f(c);
    return 0;
}

(1) accepts the object of type C, and makes a copy. Here is the output:

C()
C(C)
f<C>
~C()
~C()

So I've tried to specialize with a const C& parameter (2) to avoid this, but this simply doesn't work (apparently the reason is explained in this question).

Well, I could "pass by pointer", but that's kind of ugly. So is there some trick that would allow to do that somehow nicely?

EDIT: Oh, probably I wasn't clear. I already have a templated function

template<class T> void f(T) {...}

But now I want to specialize this function to accept a const& to another object:

template<> void f(const SpecificObject&) {...}

But it only gets called if I define it as

template<> void f(SpecificObject) {...}

Basically what I want to do with this specialization is to adapt the SpecificObject to the template interface like

template<> void f(SpecificObject obj){ f(obj.Adapted()); } // call the templated version

EDIT2: Ok, I can force the const C& specialization to be called this way:

f<const C&>(c);

but is there a way to make it work like this as just f(c)?

EDIT3: If someone would eventually have similar questions, I finally found this link in another question, and it is helpful: http://www.gotw.ca/publications/mill17.htm

解决方案

So if you don't always want to accept a const reference (which is reasonable for base types [int, long, float etc.]), you can use a little boost magic.

#include <iostream>
#include <boost/call_traits.hpp>

using namespace std;

struct C
{
  C() { cout << "C()" << endl;  }
  C(const C&) { cout << "C(C)" << endl; }
  //C& operator=(C const&) { cout << "C=C" << endl; return *this; }
  ~C() { cout << "~C()" << endl;  }
};

template<class T> void foo(typename boost::call_traits<T>::param_type inst) { cout << "f<T>" << endl; }
// specialization for calling class C
template<> void foo<C>(boost::call_traits<C>::param_type inst) { cout << "f<C>" << endl; }

int main()
{
  int i = 0;
  foo<int>(i);
  C c;
  foo<C>(c);
  return 0;
}

这篇关于模板通过const引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆