How to make a conditional typedef in C++
C++C++11C++ Problem Overview
I am trying to do something like this:
#include <iostream>
#include <random>
typedef int Integer;
#if sizeof(Integer) <= 4
typedef std::mt19937 Engine;
#else
typedef std::mt19937_64 Engine;
#endif
int main()
{
std::cout << sizeof(Integer) << std::endl;
return 0;
}
but I get this error:
error: missing binary operator before token "("
How can I correctly make the conditional typedef?
C++ Solutions
Solution 1 - C++
Use the std::conditional
meta-function from C++11.
#include <type_traits> //include this
typedef std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64>::type Engine;
Note that if the type which you use in sizeof
is a template parameter, say T
, then you have to use typename
as:
typedef typename std::conditional<sizeof(T) <= 4, // T is template parameter
std::mt19937,
std::mt19937_64>::type Engine;
Or make Engine
depend on T
as:
template<typename T>
using Engine = typename std::conditional<sizeof(T) <= 4,
std::mt19937,
std::mt19937_64>::type;
That is flexible, because now you can use it as:
Engine<int> engine1;
Engine<long> engine2;
Engine<T> engine3; // where T could be template parameter!
Solution 2 - C++
Using std::conditional
you can do it like so:
using Engine = std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64
>::type;
If you want to do a typedef
, you can do that too.
typedef std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64
>::type Engine
Solution 3 - C++
If you don't have C++11 available (although it appears you do if you're planning to use std::mt19937
), then you can implement the same thing without C++11 support using the Boost Metaprogramming Library (MPL). Here is a compilable example:
#include <boost/mpl/if.hpp>
#include <iostream>
#include <typeinfo>
namespace mpl = boost::mpl;
struct foo { };
struct bar { };
int main()
{
typedef mpl::if_c<sizeof(int) <= 4, foo, bar>::type Engine;
Engine a;
std::cout << typeid(a).name() << std::endl;
}
This prints the mangled name of foo
on my system, as an int
is 4 bytes here.