如何在C++中创建条件typedef

How to make a conditional typedef in C++

本文关键字:创建 条件 typedef C++      更新时间:2023-10-16

我正在尝试这样做:

#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?

使用C++11中的std::conditional元函数。

#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!

使用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

如果您没有可用的C++11(尽管如果您计划使用std::mt19937,则可以使用),那么您可以使用Boost元编程库(MPL)在没有C++11支持的情况下实现相同的功能。下面是一个可编译的例子:

#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个字节。