[英]How can I use templates to determine the appropriate argument passing method?
As I understand it, when passing an object to a function that's larger than a register, it's preferable to pass it as a (const) reference, eg: 据我所知,当一个对象传递给一个比寄存器大的函数时,最好将它作为(const)引用传递,例如:
void foo(const std::string& bar)
{
...
}
This avoids having to perform a potentially expensive copy of the argument. 这避免了必须执行可能昂贵的参数副本。
However, when passing a type that fits into a register, passing it as a (const) reference is at best redundant, and at worst slower: 但是,当传递适合寄存器的类型时,将其作为(const)引用传递最多是冗余的,最坏的情况是:
void foo(const int& bar)
{
...
}
My problem is, I'd like to know how to get the best of both worlds when I'm using a templated class that needs to pass around either type: 我的问题是,当我使用需要传递任何类型的模板化类时,我想知道如何充分利用这两个世界:
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);
};
Is there a template decision method that allows me to pick the correct type? 是否有模板决策方法允许我选择正确的类型? Something that would let me do,
可以让我做的事,
void bar(const_nocopy<T>::type baz);
that would pick the better method depending on the type? 根据类型选择更好的方法?
Edit: 编辑:
After a fair amount of timed tests, the difference between the two calling times is different, but very small. 经过大量的定时测试后,两个通话时间之间的差异是不同的,但非常小。 The solution is probably a dubious micro-optimization for my situation.
对于我的情况,解决方案可能是一个可疑的微优化。 Still, TMP is an interesting mental exercise.
尽管如此, TMP仍然是一项有趣的心理锻炼。
Use Boost.CallTraits : 使用Boost.CallTraits :
#include <boost/call_traits.hpp>
template <typename T>
void most_efficient( boost::call_traits<T>::param_type t ) {
// use 't'
}
If variable copy time is significant, the compiler will likely inline that instance of a template anyway, and the const reference thing will be just as efficient. 如果变量复制时间很重要,那么编译器很可能会内联该模板的实例,而const引用的东西也同样有效。
Technically you already gave yourself an answer. 从技术上讲,你已经给了自己一个答案。
Just specialize the no_copy<T>
template for all the nocopy types. 只需为所有nocopy类型专门化
no_copy<T>
模板。
template <class T> struct no_copy { typedef const T& type; };
template <> struct no_copy<int> { typedef int type; };
我能想到的唯一解决方案是使用宏为较小的类生成专用模板版本。
First: Use const &
- if the implementation is to large to be inlined, the cosnt & vs. argument doesn't make much of a difference anymore. 第一种:使用
const &
- 如果要实现大到内联,则cosnt和vs.参数不再有太大区别。
Second: This is the best I could come up with. 第二:这是我能想到的最好的。 Doesn't work correctly, because the compiler cannot deduce the argument type
无法正常工作,因为编译器无法推断出参数类型
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.