模板结构的静态const成员的不同值

时间:2015-10-23 11:44:08

标签: c++ c++11 metaprogramming

我试图制作一个小的元编程结构,它生成width位向左移位shift位的位掩码(主要用于学习目的)。以下代码在{+ 1}}的VC ++ 15上触发警告C4293(移位计数为负或太大,未定义的行为),因为它仍会触发三元运算符的第二个分支 - 即使它不是假设的影响价值本身。什么是更好,更清洁的方法来实现这一目标?

mask<64>::value;

1 个答案:

答案 0 :(得分:1)

您希望避免编译条件的冗余分支 width >= (sizeof(uintmax_t)<<3)。我只有gcc 5.1和clang 3.6 处置,但我希望VC ++ 2015也能让你这样做:

#include <cstdint>
#include <type_traits>

template <uint8_t width, uint8_t shift=0, typename Enable = void>
struct mask;

template <uint8_t width, uint8_t shift> struct 
mask<width,shift,typename std::enable_if<(width >= (sizeof(uintmax_t)<<3))>::type> 
{
    static const uintmax_t value = (~0 << shift);
    mask()=delete;
};

template <uint8_t width, uint8_t shift> struct 
mask<width,shift,typename std::enable_if<(width < (sizeof(uintmax_t)<<3))>::type> 
{
    static const uintmax_t value = (((uintmax_t(1)<<width)-1) << shift);
    mask()=delete;
};

template <class T>
struct typeMask {
    static const uintmax_t value = mask<sizeof(T)<<3>::value;
    typeMask()=delete;
};

顺便说一下,编译mask<64>::value,clang抱怨:

warning: in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension [-Wgnu-folding-constant]
static const uintmax_t value = (~0 << shift);
                               ~~~~^~~~~~~~~

您可以将~0替换为~uintmax_t(0)来更正抱怨内容。