我已经查看了几个类似的问题,但我仍然感到困惑。我试图找出如何显式(不是通过编译器优化等)和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)以避免这种情况,但这根本不起作用(显然原因在this question中有解释)。
嗯,我可以“通过指针”,但那有点难看。那么是否有一些技巧可以很好地做到这一点?
编辑:哦,可能我不清楚。我已经有模板化的功能template<class T> void f(T) {...}
但是现在我想专门化这个函数来接受一个const&amp;到另一个对象:
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&
专业化:
f<const C&>(c);
但有没有办法让它像f(c)
那样工作?
EDIT3:如果有人最终会遇到类似的问题,我终于在另一个问题中找到了这个链接,这很有帮助:http://www.gotw.ca/publications/mill17.htm
答案 0 :(得分:3)
你正在混淆三个问题:模板,重载和参数传递。
只需删除专精并将参数传递为T const&
。
干杯&amp;第h。,
答案 1 :(得分:2)
你为什么不超载:
void f(const C& c) { cout << "f(const C&)" << endl; }
答案 2 :(得分:2)
这样可行:
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)
传递给常规的
答案 3 :(得分:1)
因此,如果你不总是想接受一个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;
}
答案 4 :(得分:1)
你的问题是实际的参数c不是const,所以主模板是一个更好的匹配,因为它不需要在类型中添加'const'。如果您尝试通过值和非const引用传递的函数,编译器将告诉您它无法解决该差异。
答案 5 :(得分:0)
#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来传递给函数的所有值。我不知道这是不是你想要的。