Uro*_*327 4 c++ templates const-reference
当我有下面的伪类:
template <class T> class tmplClass
{
void doSomething(T input);
};
Run Code Online (Sandbox Code Playgroud)
有一种方法来改变void doSomething(T input)
到void doSomething(const T& input)
时的sizeof(T)是在较大的系统架构.
tmplClass<char> c;
例如,void doSomething(T input)
当您有tmplClass<[another big class with lots of variables]>
使用时,意味着使用void doSomething(const T& input)
是的,简单:
#include <type_traits>
template <typename T> struct Foo
{
void do_something(typename std::conditional<(sizeof(T) > sizeof(void *)),
T const &, T>::type x)
{
// ... use "x"
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
您可能希望将结果类型分配给某些类型别名,以便于重用.
正如@Yakk建议的那样,也可以添加std::is_trivially_copyable<T>::value
条件以避免意外复制复制或可能丢弃的东西.
当然:
template<typename T, bool=true>
struct eff_arg {
typedef T type;
};
template<typename T>
struct eff_arg<T, (sizeof(T)>sizeof(int))> {
typedef T const& type;
};
// C++11 addition
template<typename T>
using EffArg = typename eff_arg<T>::type;
Run Code Online (Sandbox Code Playgroud)
使用:
template <class T> class tmplClass
{
// C++11
void doSomething(EffArg<T> input);
// C++03
void doSomething(typename eff_arg<T>::type input);
};
Run Code Online (Sandbox Code Playgroud)
并替换sizeof(int)
为您要用作"要作为参考而不是按值传递的点"的任何类型.
请注意,参数的大小是做出此决定的平庸方式:极小的类(甚至小于指针!)可能具有深层复制语义,其中大型结构在复制时会重复.通常情况下,截止不应该是int
指针的大小或指针,而应该大于指针的大小,因为间接成本是有代价的.
一个想法可能是仅复制不管理资源且足够小的对象. std::is_trivially_copyable<T>::value && (sizeof(T) <= 2*sizeof(void*))
可能是在传递a之前应该进行的检查,T
而不是T const&
在不需要数据副本时进行的检查.
这导致以下结果:
template<typename T, bool=true>
struct eff_arg {
typedef T const& type;
};
template<typename T>
struct eff_arg<T,
std::is_trivially_copyable<T>::value
&& (sizeof(T)<=2*sizeof(void*))
> {
typedef T type;
};
template<typename T>
using EffArg = typename eff_arg<T>::type;
Run Code Online (Sandbox Code Playgroud)