If I have a little peice o' code as such...
template <typename _T>
class Foo
{
public:
    typedef const T& ParamType;
    void DoStuff(ParamType thingy);
};
This can be non-optimal if sizeof(_T) <= sizeof(_T*).
Therefore, I want to have a conditional typedef. If the size of _T is less than or equal to that of a pointer, just pass it in by value. Otherwise, pass it by const reference. Is this possible? I hear all this stuff about templates being turing complete but this is hurting my head.
Quite easy to achieve using partial template specialization.
template< typename _T, bool _ByVal >
struct FooBase {
  typedef const _T& ParamType;
};
template< typename _T >
struct FooBase< _T, true > {
  typedef const _T ParamType;
};
template< typename _T, bool _ByVal = sizeof(_T) <= sizeof(void*) >
class Foo : public FooBase< _T, _ByVal > {
  typedef typename FooBase< _T, _ByVal >::ParamType ParamType;
  void DoStuff(ParamType thingy);
};
EDIT As per Jeff's sol'n one should indeed compare sizeof(_T) and sizeof(_T&) but I kept the original <= void* requirement.
You can do that, but it's a little tricky.
My main concern here if your motive. I understand that you don't want to pass large objects by value, but whether or not the object is large is irrelevant -- what you really want to know is how long the copy constructor takes to create the parameter.
As a concrete example, the size of an std::vector is actually very tiny as it allocates all the memory on the heap and only needs a pointer. However, copying a vector takes much more time. Something like that is not something you can really include in a condition.
You're best bet here is to just pass by const & so that you cover the worst case. Also, I can't guarantee this, but the I believe that a compiler would be smart enough to pass by value if it thought that was more efficient.
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