【问题标题】:Handling int and std::vector::size_type in comparsion比较处理 int 和 std::vector::size_type
【发布时间】:2020-03-06 13:51:09
【问题描述】:

所以我有这样的东西(C++03):

class MyClass
{
    // ...
}

class something
{
    private:
        std::vector<MyClass*> container;
    // ...
}

// cmdarg can be anything, negative int too...
void something::foo(const std::string& cmdarg)
{
    const int res = std::stoi(cmdarg);
    if (res >= 0 && static_cast<std::vector<MyClass*>::size_type>(res) < this->container.size())
    {
        // ...
    }
}

我想问一下从intstd::vector&lt;MyClass*&gt;::size_type 的转换是否有效。 res &gt;= 0 表示它不是负数,所以我想转换为另一个非负数是好的。

我的问题是,如果我写

if (res >= 0 && res < container.size())

由于与有符号和无符号整数类型的比较,我收到了一条警告。

我上面的代码(完整的)编译并且似乎可以工作,但我不确定。

谢谢。

【问题讨论】:

  • 如果你确定 int 永远不会是负数,那么你可以将它声明为 size_t 或强制转换为 size_t
  • 这在我看来像是代码审查堆栈交换的东西
  • 在实践中,使用static_cast&lt;unsigned&gt;static_cast&lt;size_t&gt; 就足够了。如果您正在编写模板,那么您在此处显示的内容将是合适的。
  • 我想警告没有考虑是否执行比较,只是检查类型。强制转换可以使警告消失,std::size_t 不太可能小于unsigned int
  • @JHBonarius:例如,如果 cmdarg == "-5",它会给出一个很大的正整数,并且 res >= 0 为真。

标签: c++ int c++03 size-type


【解决方案1】:

你的代码对我来说有点太完美了。

分解:

const int res = std::stoi(cmdarg);
if (res >= 0 && static_cast<std::vector<MyClass*>::size_type>(res) < this->container.size())

检查零以下的 if 语句很好。我个人会这样写:

if (res < 0)
{
    std::cerr << "Negative number " << res <<" given for ..., a positive was expected" << std::endl;
    return -1;
}

这将我们引向演员:

auto unsigned_res = static_cast<std::vector<MyClass*>::size_type>(res);

然而,size_type 这个向量总是size_t,因为它使用std::allocator。在代码审查中,我会要求将其更改为:

auto unsigned_res = static_cast<std::size_t>(res);

最后,你确实可以很好地比较它:

if (unsiged_res < container.size())
    // Do something

请注意,我提到了比较和演员表,因为这需要按此顺序进行。最重要的是,当std::stoi 失败时,您还需要一些异常处理,请参阅it's documentation

关于如何正确处理有符号/无符号的更多细节,我可以在 itare 上推荐this article

【讨论】:

    猜你喜欢
    • 2021-01-26
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    相关资源
    最近更新 更多