我正在用 clang 3.3 编译一些似乎可以用 gcc 4.8 编译的代码:
原始代码是:
template <std::size_t N> struct helper { typedef void type; };
template <> struct helper<64> { typedef int64_t type; };
template <> struct helper<32> { typedef int32_t type; };
template <> struct helper<16> { typedef int16_t type; };
template <> struct helper<8> { typedef int8_t type; };
template <std::size_t I, std::size_t F>
struct test
{
typedef typename helper<I+F>::type value_type;
static constexpr std::size_t frac_mask = ~((~value_type(0)) << F);
};
在铿锵声中,如果我尝试声明 test<16,16> 或 test<8,0> 我会收到错误消息:
test.cpp:41:34:错误:constexpr 变量“frac_mask”必须由常量表达式初始化
static constexpr std::size_t frac_mask = ~((~value_type(0)) << F);
如果我将代码转换为:
template <std::size_t I, std::size_t F>
struct test
{
typedef typename helper<I+F>::type value_type;
typedef typename std::make_unsigned<value_type>::type mask_type;
static constexpr mask_type frac_mask = ~((~mask_type(0)) << F);
};
它在大多数情况下都可以编译(I、F 的值),但如果我声明 test<8, 0>,我会收到错误消息:
test.cpp:23:36:错误:constexpr 变量“frac_mask”必须由常量表达式初始化
test.cpp:66:15:注意:在此处请求的模板类 'test<8, 0>' 的实例化中
test.cpp:23:66:注意:负值左移-1
static constexpr mask_type frac_mask = ~((~mask_type(0)) << F);
我的问题是 - 就 constexpr 的规范而言,我在这里违反了一些规则吗?此外,对于最后一个错误 - 掩码类型是无符号的 - 这是一个编译器问题,它认为我正在转移一个负值还是我误读了代码?