编译迭代器使用的时间验证?

时间:2012-10-01 17:40:12

标签: c++ visual-studio-2010 c++11 iterator erase

我有一些粗心的C ++代码,它在VC10下编译顺利,但在运行时失败了。我想知道是否有一种方法可以在编译时验证这种错误?

#include "stdafx.h"
#include <set>

void minus(std::set<int>& lhs, const std::set<int>& rhs)
{
    for ( auto i = rhs.cbegin(); i != rhs.cend(); ++i )
    {
        lhs.erase(i); // !!! while I meant "*i" !!!
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    int v_lhs[] = {0,1,2,3,4,5};
    std::set<int> s_lhs(&v_lhs[0], &v_lhs[sizeof(v_lhs) / sizeof(int)]);

    int v_rhs[] = {1,3,5};
    std::set<int> s_rhs(&v_rhs[0], &v_rhs[sizeof(v_rhs) / sizeof(int)]);

    minus(s_lhs, s_rhs);
    return 0;
}

请注意,我完全清楚C ++ 11(由VC10早期部分采用)已经纠正了'erase'实际上采用“const_iterator”的行为。

提前感谢任何有价值的投入。

1 个答案:

答案 0 :(得分:2)

C ++不是一种思维阅读语言。它只知道类型。它知道erase需要一个迭代器。它知道i是同一类型的迭代器。因此,就编译器的C ++规则而言,调用erase(i)是合法的。

编译器无法知道你的意思要做什么。编译器也没有办法知道i内容不适合erase的特定用法。你最好的办法是尽量避免错误。基于范围的for(或使用std::for_each)可以帮助您,因为这两个都隐藏了迭代器。