繁体   English   中英

模板通过const参考传递

[英]template pass by const reference

我看了几个类似的问题,但我仍然感到困惑。 我试图找出如何显式 (而不是通过编译器优化等)和与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; }

// 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)接受类型C的对象,并进行复制。 这是输出:

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

因此,我尝试专门使用const C&参数(2)来避免这种情况,但这根本行不通(显然原因在此问题中得到了解释)。

好吧,我可以“通过指针”,但这有点丑陋。 那么,是否有一些技巧可以使它更好地实现呢?

编辑:哦,可能我不清楚。 我已经有一个模板化的功能

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

但是现在我想专门化此函数以接受const&到另一个对象:

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

但是只有我定义为

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

基本上,我想对这种专业化进行处理是使SpecificObject适应模板接口,例如

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

EDIT2:好的,我可以这样强制const C& specialization:

f<const C&>(c);

但是有没有办法像f(c)那样使它工作呢?

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

您正在混淆三个问题:模板,重载和参数传递。

只需删除专长并将参数传递为T const&

干杯,……

你为什么不超载:

void f(const C& c) { cout << "f(const C&)" << endl; }

这将工作:

int main()
{
    C c;
    f<const C&>(c);
    return 0;
}

您的选择:

template<typename T> void f(const boost::reference_wrapper<T const>& c) 
    { cout << "f<boost_const_ref&>" << endl; } 

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

实际上,您可以使用boost :: reference_wrapper将引用传递到您要使用它的位置。 您可以使用get()来做到这一点,尽管boost :: reference_wrapper具有隐式转换回引用的功能,所以您可能不需要模板的部分专业化,而只需将boost::cref(c)传递给常规的。

因此,如果您不总是希望接受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; }
// 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;
}

您的问题是实际参数c不是const,因此主模板是更好的匹配,因为它不需要在类型中添加'const'。 如果您尝试按值传递和按非const引用传递的函数,则编译器将告诉您它无法解决该差异。

#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(const T&) { cout << "f<T>" << endl; }

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

这确实可以实现您想要的功能,但是您必须对所有传递给函数的值使用const ref。 我不知道这是否是您想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM