When I have following pseudo-class:
template <class T> class tmplClass
{
void doSomething(T input);
};
Is there a way to change void doSomething(T input)
to void doSomething(const T& input)
when sizeof(T) is larger the the system architecture.
Means, when you have tmplClass<char> c;
for example, use void doSomething(T input)
and when you have tmplClass<[another big class with lots of variables]>
use void doSomething(const T& input)
Sure:
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;
use:
template <class T> class tmplClass
{
// C++11
void doSomething(EffArg<T> input);
// C++03
void doSomething(typename eff_arg<T>::type input);
};
and replace sizeof(int)
with whatever type you want to use as the "point where you want to pass as a reference instead of by value".
Note that the size of a parameter is a mediocre way to make this decision: An extremely small class (even smaller than a pointer!) could have deep copy semantics where a large structure is duplicated when it is duplicated. And often the cut-off shouldn't be size of int
or a pointer but bigger than that, because indirection has a cost.
An idea might be to copy only objects that don't manage resources and are sufficiently small. std::is_trivially_copyable<T>::value && (sizeof(T) <= 2*sizeof(void*))
might be the kind of check you should make before passing a T
rather than a T const&
when you have no need for a copy of the data.
This leads to the following:
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;
Yes, easy:
#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"
}
// ...
};
You might want to assign the resulting type to some type alias for easy reuse.
As @Yakk suggests, it might be good to also add std::is_trivially_copyable<T>::value
to the condition to avoid accidentally copying something that's expensive to copy or that might throw.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With