我如何使用模板来确定适当的参数传递方法?

据我所知,当将一个对象传递给一个大于寄存器的函数时,最好将它作为(const)引用传递,例如:

void foo(const std::string& bar)
{
    ...
}
这避免了必须执行一个潜在的昂贵的参数副本。 然而,当传入一个适合寄存器的类型时,传递它作为(const)引用最多是多余的,最坏的情况是:
void foo(const int& bar)
{
    ...
}
我的问题是,我想知道如何在使用需要传递任何类型的模板类时获得两全其美的优势:
template <typename T>
class Foo
{
  public:
// Good for complex types, bad for small types
    void bar(const T& baz);
// Good for small types, but will needlessly copy complex types
    void bar2(T baz);             
};
有没有一种模板决策方法可以让我选择正确的类型?有些事情可以让我做,
void bar(const_nocopy<T>::type baz);
那会根据类型选择更好的方法?
编辑: 经过相当数量的定时测试后,两次调用时间之间的差异是不同的,但非常小。这个解决方案对我的情况来说可能是一个可疑的微观优化。尽管如此,TMP是一个有趣的心理练习。
已邀请:

bsint

赞同来自:

如果可变拷贝时间很长,那么编译器可能会内联这个模板的实例,而const引用的东西将会同样有效。 从技术上讲,你已经给了自己一个答案。 只需为所有nocopy类型专门设计no_copy<T>模板。

template <class T> struct no_copy { typedef const T& type; };
template <> struct no_copy<int> { typedef int type; };

qnon

赞同来自:

我能想到的唯一解决方案是使用宏为较小的类生成专用模板版本。

adolor

赞同来自:

首先:使用const & - 如果执行内容很大以便内联,则可以使用cosnt&与争论不再有很大区别。 第二:这是我能想到的最好的。无法正常工作,因为编译器无法推断参数类型

template <typename T, bool UseRef> 
struct ArgTypeProvider {};
template <typename T>
struct ArgTypeProvider<T, true>
{
   typedef T const & ArgType;
};
template <typename T>
struct ArgTypeProvider<T, false>
{
   typedef T ArgType;
};
template <typename T>
struct ArgTypeProvider2 : public ArgTypeProvider<T, (sizeof(T)>sizeof(long)) >
{
};
// ----- example function
template <typename T>
void Foo(typename ArgTypeProvider2<T>::ArgType arg)
{
   cout << arg;
}
// ----- use
std::string s="fdsfsfsd";
// doesn't work :-(
// Foo(7);
// Foo(s);
// works :-)
Foo<int>(7);
Foo<std::string>(s);

ha

赞同来自:

使用Boost.CallTraits

#include <boost/call_traits.hpp>
template <typename T>
void most_efficient( boost::call_traits<T>::param_type t ) {
    // use 't'
}

要回复问题请先登录注册