使用常量来设置变量类型

时间:2013-07-29 19:12:45

标签: c++ const c-preprocessor

我想知道,如果这样:

#define size 8
#if ( 0 < size ) and ( size <= 16 )
  static unsigned char value;
#elif ( 8 < size ) and  ( size <= 16 )
  static unsigned short value;
#elif ( 16 < size ) and  ( size <= 32 )
  static unsigned value;
#elif ( 32 < size ) and  ( size <= 64 )
  static unsigned long value;
#else
  return 0;
#endif
#undef size

可以使用常量吗?我试过了:

const unsigned char size = 8;
if ( ( 0 < size ) &&  ( size <= 8 ) ) {
  static unsigned char value;
} else if ( ( 8 < size ) &&  ( size <= 16 ) ) {
  static unsigned short value;
} else if ( ( 16 < size ) &&  ( size <= 32 ) ) {
  static unsigned value;
} else if ( ( 32 < size ) &&  ( size <= 64 ) ) {
  static unsigned long value;
} else {
  return 0;
}

但结果我得到了:

  

致命错误:使用未声明的标识符'value'

这可能吗?

3 个答案:

答案 0 :(得分:1)

您不能在运行时为变量使用不同的类型。类型在编译时确定。

所以,第一个选项有效,但第二个选项不起作用。

当然,可能存在有效的模板解决方案,例如下面的建议。

要创建位图,是的,请使用std::bitset<size>,其中size是位数。这将适用于从0开始的任意位数,以及适合您的内存或地址空间的任何位数,无论哪个先用完。

答案 1 :(得分:1)

你可以使用

typedef boost::uint_t<16>::exact my_uint16_t;
typedef boost::uint_t<8>::exact  my_uint8_t;
// etc.

这适用于编译时常量:

constexpr int mybitcount = 8;

void foo(boost::uint_t<mybitcount> ui8)
{
}

请参阅Boost Integer

template<int Bits>
struct uint_t 
{
    /* Member exact may or may not be defined depending upon Bits */
    typedef implementation-defined-type  exact;
    typedef implementation-defined-type  least;
    typedef uint_fast_t<least>::fast      fast;
};

答案 2 :(得分:0)

您可以将std::conditional用作:

template<int N>
using uint = typename std::conditional< N<=8, unsigned char,
                           std::conditional< N<=16, unsigned short,
                                std::conditional< N<=32, unsigned int
                                     std::conditional< N<=64, unsigned long,
                                          void>>>>:type;

然后将其用作:

uint<8>   _08BitsUInt; //as long as N <= 8
uint<16>  _16BitsUInt; //as long as N <=16 and N > 8
uint<32>  _32BitsUInt; //as long as N <=32 and N > 16
uint<64>  _64BitsUInt; //as long as N <=64 and N > 32

希望有所帮助。