【问题标题】:error unary minus operator applied to unsigned type results in unsigned错误一元减号运算符应用于无符号类型导致无符号
【发布时间】:2017-10-05 20:49:37
【问题描述】:

目前我的代码中有一个函数可以将数字类型转换为字符串。由于我没有使用std::to_string 的原因。现在这段代码在 XCode 上构建得很好,但窗口似乎在抱怨。 windows 抱怨的原因是因为有一次我传递了一个无符号类型,然后对它做负数仍然保持正数,因为该类型是无符号的。我的问题是我可以放一个 if 类来检查类型是否已签名然后输入条件吗?这样能解决问题吗

    template<typename t>
    std::string MyFunct(t num,int base=10)
    {
        char str [sizeof(t)*8+1];
        int i = 0;
        bool isNegative = false;


        if (num == 0)
        {
            str[i++] = '0';
            str[i] = '\0';
            return str;
        }

        //Negative only when base is 10
        if (num < 0 && base == 10)
        {
            isNegative = true;
            num = -num; //<------ERROR in case the type is unsigned
        }
        ....
        ....
    }

我该如何解决这个问题?有没有办法让我告诉编译器只有当类型是无符号的时候才进入这里?

【问题讨论】:

  • 好吧,你可以试试num = num * (1 - 2 * std::is_unsigned&lt;T&gt;::value)。但是,不知道它是否能达到您想要的效果。
  • @JohnB 如果 std::is_unsigned&lt;T&gt;::value 未签名,它会输出什么?
  • true,我猜。可能num = num * (1 - (std::is_unsigned&lt;T&gt;::value ? 2 : 0) ) 是正确的方法。
  • 你不能简单地写num = (T) (-1) * num;吗?
  • 请禁用这个愚蠢的警告并签署请愿书,让微软永久删除它。

标签: c++ c++11 unsigned signed


【解决方案1】:

使用支持 C++17 的现代编译器,one could use constexpr ifstd::numeric_limits&lt;T&gt;::is_signed 仅对有符号整数类型执行否定。请注意,普通的if 仍然可能导致编译器进行诊断,constexpr if 是必需的。

constexpr if 的替代方案是一个相当简单的模板特化:

template<typename t, bool is_signed=std::numeric_limits<T>::is_signed>
    std::string MyFunct(t num,int base=10);

template<typename t>
std::string MyFunct<t, true>(t num,int base10)
{
    // The signed specialization of MyFunct()
}

template<typename t>
std::string MyFunct<t, false>(t num,int base)
{
    // The unsigned specialization of MyFunct()
}

只有转换函数的签名版本会使用否定逻辑。当然,您的函数的签名和未签名版本都会有很多共同的代码。但是现在这变成了一种简单直接重构的普通情况。

【讨论】:

  • num = num * (1 - 2 * std::is_unsigned&lt;T&gt;::value) 怎么样?正如@JohnB 建议的那样?我想知道 std::is_unsigned&lt;T&gt;::value 如果类型是有符号的,如果它是无符号的,返回什么?
  • 您的 Google 是否在过去两个小时内出现故障,因此您无法查看 std::is_unsigned&lt;T&gt;::value 返回的内容?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2011-12-23
相关资源
最近更新 更多