1

私は次の不注意な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」を取る動作を修正したことを私は完全に知っていることに注意してください。

貴重なご意見をよろしくお願いいたします。

4

1 に答える 1

2

C++は読みやすい言語ではありません。それが知っているのはタイプだけです。それeraseはイテレータが必要であることを知っています。iそして、それが同じタイプのイテレータであることを知っています。したがって、C ++のコンパイラの規則に関する限り、を呼び出すことは合法erase(i)です。

コンパイラがあなたが何をしようとしていたかを知る方法はありませ。また、コンパイラがの内容iこの特定の使用に適していないことを知る方法もありませんerase。あなたの最善の策は、間違いを避けるようにすることです。範囲ベースfor(またはの使用std::for_each)は、どちらもイテレータを非表示にするため、ここで役立ちます。

于 2012-10-01T20:31:57.507 に答える