当前位置:  开发笔记 > 编程语言 > 正文

大多数签名/未签名警告的可接受修复?

如何解决《大多数签名/未签名警告的可接受修复?》经验,为你挑选了1个好方法。

我自己确信,在一个项目中,我正在研究有符号整数是大多数情况下的最佳选择,即使其中包含的值永远不会是负数.(更简单的循环反转,更少的错误机会等,特别是对于只能保持0和20之间的值的整数,无论​​如何.)

出现问题的大多数地方是std :: vector的简单迭代,过去常常是一个数组,之后变为std :: vector.所以这些循环通常如下所示:

for (int i = 0; i < someVector.size(); ++i) { /* do stuff */ }

由于此模式经常使用,因此编译器警告垃圾邮件的数量与签名和未签名类型之间的此比较往往隐藏更多有用的警告.请注意,我们肯定没有带有多个INT_MAX元素的向量,并注意到目前为止我们使用了两种方法来修复编译器警告:

for (unsigned i = 0; i < someVector.size(); ++i) { /*do stuff*/ }

这通常有效但如果循环包含任何代码,如'if(i-1> = 0)......'等,可能会默默地中断.

for (int i = 0; i < static_cast(someVector.size()); ++i) { /*do stuff*/ }

这种变化没有任何副作用,但它确实使循环的可读性降低了很多.(而且它打字更多.)

所以我提出了以下想法:

template  struct vector : public std::vector
{
    typedef std::vector base;

    int size() const     { return base::size(); }
    int max_size() const { return base::max_size(); }
    int capacity() const { return base::capacity(); }

    vector()                  : base() {}
    vector(int n)             : base(n) {}
    vector(int n, const T& t) : base(n, t) {}
    vector(const base& other) : base(other) {}
};

template  struct map : public std::map
{
    typedef std::map base;
    typedef typename base::key_compare key_compare;

    int size() const     { return base::size(); }
    int max_size() const { return base::max_size(); }

    int erase(const Key& k) { return base::erase(k); }
    int count(const Key& k) { return base::count(k); }

    map() : base() {}
    map(const key_compare& comp) : base(comp) {}
    template  map(InputIterator f, InputIterator l) : base(f, l) {}
    template  map(InputIterator f, InputIterator l, const key_compare& comp) : base(f, l, comp) {}
    map(const base& other) : base(other) {}
};

// TODO: similar code for other container types

你看到的基本上是STL类,其方法是返回size_type,只返回'int'.需要构造函数,因为它们不是继承的.

如果您在现有代码库中看到这样的解决方案,您会如何看待这个开发人员?

你会想到'whaa,他们正在重新定义STL,这是一个巨大的WTF!',或者你认为这是一个很好的简单解决方案来防止错误和提高可读性.或者你可能更愿意看到我们花了一半左右的时间来改变所有这些循环以使用std :: vector <> :: iterator?

(特别是如果这个解决方案与禁止使用无符号类型除了原始数据(例如unsigned char)和位掩码之外的任何东西.)



1> fizzer..:

不要公开从STL容器中派生.它们具有非虚拟析构函数,如果有人通过指向基类删除其中一个对象,则会调用未定义的行为.如果必须从向量派生,请私下进行,并使用using声明公开需要公开的部分.

在这里,我只使用a size_t作为循环变量.它简单易读.评论说使用int索引将你公开为n00b 的海报是正确的.但是,使用迭代器循环遍历向量会将您暴露为稍微有点经验的n00b - 一个没有意识到向量的下标运算符是常量时间的n00b.(vector::size_type准确,但不必要的详细IMO).


实现目标的一种方法是size_t足以保存任何对象的大小,并且保证向量由连续存储支持,因此size_type <= size_t
推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有