繁体   English   中英

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

[英]Different values of a static const member of a template struct

我正在尝试制作一个小的元编程结构,该结构将生成width向左移动shift位置(主要用于学习)的位掩码。 下面的代码在VC ++ 15上为mask<64>::value;触发警告C4293(移位计数为负数或太大,未定义行为) mask<64>::value; ,因为它仍然会触发三元运算符的第二个分支-即使它不应该影响值本身。 有什么更好,更清洁的方法来实现这一目标?

// Bitmask of 'width' bits shifted 'shift' bits to the left
// For instance, mask<16,8> := 0x00FFFF00 
template <uint8_t width, uint8_t shift=0>
struct mask {
    static const uintmax_t value = (width >= (sizeof(uintmax_t)<<3)) ?
            (~0 << shift) : (((uintmax_t(1)<<width)-1) << shift) ;
    mask()=delete;
};

// A bitmask for a type, for instance, 0xFF for uint8_t
template <class T>
struct typeMask {
    static const uintmax_t value = mask<sizeof(T)<<3>::value;
    typeMask()=delete;
};

您要避免编译条件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 ,c抱怨:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM