【问题标题】:Unsigned Char Template Value Overflow无符号字符模板值溢出
【发布时间】:2014-10-12 20:03:27
【问题描述】:

我正在使用以下模板对 unsigned char 值进行编码:

template <unsigned char val>
struct Cell {
    enum { value = val };

    using add = Cell<val + 1>;
    using sub = Cell<val - 1>;
};

我希望 sub 在溢出方面表现得像标准的 unsigned char 变量:

unsigned char x = 0;
x - 1; // 255

但是我在 Clang 中得到一个编译器错误:

using cell = Cell<0>;
cell::sub::value; // Error here.


Non-type template argument evaluates to -1, which cannot be narrowed to type 'unsigned char'

在模板上下文中溢出的处理方式不同吗?

【问题讨论】:

    标签: c++ templates template-meta-programming


    【解决方案1】:

    val - 1 是您平台上的int,因为通常的算术转换。为 unsigned char 类型的模板参数赋予 int 参数没有任何意义。

    只需确保您的模板参数具有所需的类型:

    using sub = Cell<static_cast<unsigned char>(val - 1U)>;
    //               ^^^^^^^^^^^^^^^^^^^^^^^^^^       ^^
    

    (使用unsigned int 字面量意味着通常的转换会产生unsigned int,它具有明确定义的缩窄语义。)

    【讨论】:

    • 感谢您为我指明正确的方向并提供解决方案。这是一篇更详细地解释 c++ 积分提升的文章:en.cppreference.com/w/cpp/language/…
    • @KerrekSB 啊,对。 unsigned int 也是可以的。
    • “给 unsigned char 类型的模板参数赋予一个 int 参数没有合理的意义。” 我认为这是可能的,只是可能不是缩小范围转换。即,val - 1 可以转换为unsigned char,只要val &gt; 0
    • @dyp:是的,每个问题都可以通过禁止除问题的可解决子集之外的所有问题来解决。假设我说的是“一般”,除非另有说明:-S
    • 嗯,我指的是 5.19/3 “T 类型的转换常量表达式是一个表达式,隐式转换为 T 类型的纯右值,其中转换后的表达式是核心常量表达式和隐式转换序列仅包含 [列表的一些转换],而不是缩小转换。” [temp.arg.nontype]/5 使用它来指定模板非类型参数允许的转换。
    猜你喜欢
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 2016-05-22
    • 1970-01-01
    • 2011-04-23
    相关资源
    最近更新 更多