Как сделать условный typedef в С++
Я пытаюсь сделать что-то вроде этого:
#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;
}
но я получаю эту ошибку:
error: missing binary operator before token "("
Как я могу правильно сделать условный typedef?
Ответы
Ответ 1
Используйте мета-функцию std::conditional
из С++ 11.
#include <type_traits> //include this
typedef std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64>::type Engine;
Обратите внимание, что если тип, который вы используете в sizeof
, является параметром шаблона, скажем T
, тогда вы должны использовать typename
как:
typedef typename std::conditional<sizeof(T) <= 4, // T is template parameter
std::mt19937,
std::mt19937_64>::type Engine;
Или заставьте Engine
зависеть от T
как:
template<typename T>
using Engine = typename std::conditional<sizeof(T) <= 4,
std::mt19937,
std::mt19937_64>::type;
Это гибкий, потому что теперь вы можете использовать его как:
Engine<int> engine1;
Engine<long> engine2;
Engine<T> engine3; // where T could be template parameter!
Ответ 2
Используя std::conditional
, вы можете сделать это так:
using Engine = std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64
>::type;
Если вы хотите сделать typedef
, вы тоже можете это сделать.
typedef std::conditional<sizeof(int) <= 4,
std::mt19937,
std::mt19937_64
>::type Engine
Ответ 3
Если у вас нет доступного С++ 11 (хотя он появляется, если вы планируете использовать std::mt19937
), тогда вы можете реализовать одно и то же без поддержки С++ 11, используя Увеличить библиотеку метапрограммирования (MPL). Вот компилируемый пример:
#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;
}
Это печатает измененное имя foo
в моей системе, так как int
здесь 4 байта.