Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional typedefs

Tags:

c++

templates

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.

like image 297
Clark Gaebel Avatar asked Feb 28 '10 00:02

Clark Gaebel


2 Answers

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.

like image 75
vladr Avatar answered Sep 22 '22 05:09

vladr


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.

like image 39
Peter Alexander Avatar answered Sep 22 '22 05:09

Peter Alexander