【问题标题】:Different values of a static const member of a template struct模板结构的静态 const 成员的不同值
【发布时间】:2015-10-23 11:44:08
【问题描述】:

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

// 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;
};

【问题讨论】:

  • 实际的错误信息是比“C4293”更有用的信息。很少有人能记住 VC++ 的错误代码。
  • 哎呀,本来想放的,最后忘记了。固定的!谢谢!

标签: c++ c++11 metaprogramming


【解决方案1】:

您希望避免编译条件的冗余分支 width &gt;= (sizeof(uintmax_t)&lt;&lt;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&lt;64&gt;::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) 来纠正它所抱怨的内容。

【讨论】:

    猜你喜欢
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多