2

次のコードは、非 const イテレータを使用して行をコンパイルするのに、 const イテレータ(Visual Studio 2008 を使用)では失敗するのはなぜですか?

#include <vector>

using std::vector;

int main(int argc, char* argv[])
{
    vector<int> test;

    test.push_back(1);
    test.push_back(2);

    vector<int>::const_iterator cit = test.end();
    std::distance(test.begin(), cit); // error: template parameter is ambiguous

    vector<int>::iterator it = test.end();
    std::distance(test.begin(), it);

    return 0;
}

注: Visual Studio 2008 にはcbegin()、あいまいさを回避するためのベクター メンバー関数はありませんが、オーバーロードされたbegin()メソッドがあります。

iterator begin()
    {   // return iterator for beginning of mutable sequence
    return (iterator(_Myfirst, this));
    }

const_iterator begin() const
    {   // return iterator for beginning of nonmutable sequence
    return (const_iterator(_Myfirst, this));
    }
4

4 に答える 4

2

テンプレートdistanceは 1 つの引数を取りますdistance<T>(T first, T last)test.begin()has typeiteratorcithas typeであるためconst_iterator、テンプレート引数は推測できません。

を使用test.cbegin()して保証を取得するかconst_iterator、そうでなければ言うことができますstatic_cast<std::vector<int> const &>(test).begin()

max<T>(T x, T y)(これは、あなたが持っていて言おうとした場合と同じですmax(1, 2U)-- あいまいなのでコンパイルされません。)

于 2012-08-06T08:47:30.220 に答える
1

注:Visual Studio 2008にはcbegin()、あいまいさを回避するためのベクトルメンバー関数はありませんが、begin()メソッドがオーバーロードされています。

コンパイラは常に非constオブジェクトに対してはnon-constオーバーロードを選択し、constメソッドはconstオブジェクトに対してのみ選択すると思います。

呼び出し

std::distance(test.begin(), cit);

のオーバーロードセットbeginとのタイプを調べcit、一致するかどうかを判断します。最初に過負荷を(非定数バージョンに)解決するため、失敗します。

コンパイラーでも機能する意図を表現する最もクリーンな方法は、おそらく次のとおりです。

vector<int> const &cref = test;
vector<int>::const_iterator cit = cref.end();
std::distance(cref.begin(), cit);
于 2012-08-06T09:32:20.200 に答える
0

関数テンプレートstd::distanceは、両方の関数引数で同じでなければならない単一のテンプレート引数のみを受け取ります。の戻り値の型test.begin()は単純iteratorに であり、 ではない const_iteratorため、関数の引数の型は異なります。コンパイラはstd::vector<int>::iterator1 番目と std::vector<int>::const_iterator2 番目を推論するため、推論は失敗します。テンプレート引数推定では、最も単純な変換を除いて、可能な変換は考慮されません。

回避する方法はたくさんありますが、いずれも顕著な欠点があります。cbegin(委員会がand 関数を追加したのはおそらくcendそのためです。) 今のところ、最善の策は、おそらく , をやめて、両方constを使用することです。iterator

于 2012-08-06T08:53:40.743 に答える
0

distance同じ時刻のテンプレート引数が必要です。この場合は です_Vector_const_iteratorbeginconst と non-constの 2 つのオーバーロードがあります。const-version は を生成します_Vector_const_iteratorが、別のバージョンは を生成し_Vector_iteratorます。_Vector_iteratorから継承し_Vector_const_iteratorます。

そのため、const と non-const の両方のオーバーロードがbegin生成可能で_Vector_const_iteratorあり、どちらも非 const オブジェクトに対して選択できます。つまり、コンパイラが混乱します。

これは私がそれをコンパイルする方法です:

    std::distance(((const vector<int>&)test).begin(), cit);
于 2012-08-06T09:00:31.960 に答える