0

以下のコードスニペットに似たものに遭遇しました。これは、を使用しているためにコンパイラエラーをスローしますconst_iteratorvec.end()inが暗黙的にキャストstd::copyを取得しない理由はありますか?const

int main(int argc, char* argv[]) {

    vector<int> vec;
    vec.push_back(20);
    vec.push_back(30);
    vector<int> copy_vec;
    vector<int>::const_iterator i = vec.begin();
    std::copy(i,vec.end(),back_inserter(copy_vec));
    cerr<<copy_vec.size()<<endl;
    return 0;
}
4

3 に答える 3

5

の必要はありませんstd::copy。また、イテレータのペアも必要ありません。

これを行うだけです:

vector<int> copy_vec(vec); //use the copy constructor!

そして、あなたは完了です!

あなたのコードに関して、それがエラーを出す理由は、最初のイテレータがであるためstd::copyですconst_iteratorが、2番目のイテレータはちょうどiteratorです。std::copy両方とも同じタイプである必要がありますが、そうではありません。そのため、関数テンプレートであるテンプレート引数の推定は失敗します。

例でこれを理解するために、次の単純なコードを考えてみましょう。

template<typename T>
void f(T a, T b) {}

int main()
{
    int a = 100;
    char b = 'A';
    f(a,b);
}

エラーが発生しています(ideoneを参照)。

prog.cpp:8: error: no matching function for call to ‘f(int&, char&)’

テンプレート引数の推定に依存しているため、コンパイルされません。関数テンプレートでは、最初のパラメーターと2番目のパラメーターのタイプはまったく同じですが、この関数を呼び出して()を最初の引数として、()を2番目の引数として渡すaためintb異なるタイプの引数から一意にchar推測することはできません。テンプレート引数の推論では、変換は考慮されないことに注意してください。T

ただし、テンプレート引数の推論に依存せず、代わりにテンプレート引数を明示的に指定すると、機能します(ideoneを参照)。

f<int>(a,b);  //works!

関数の引数から推測する必要がないのでT機能します!

同様に、のテンプレート引数を指定するとstd::copy、コードでも機能します(ideoneを参照)。

std::copy<vector<int>::const_iterator>(i,vec.end(),back_inserter(copy_vec));
       //^^^^^^^^^^^^^^^^^^^^^^^^^^^^ explicitly provide template argument!

iterator変換できるため機能しますがconst_iterator、にconst_iterator変換できないためiterator、次のエラーが発生します(ideoneを参照)。

std::copy<vector<int>::iterator>(i,vec.end(),back_inserter(copy_vec));
        //^^^^^^^^^^^^^^^^^^^^^ non-const iterator!
于 2011-11-10T05:42:08.670 に答える
1

vecは非定数ベクトルであるためend、非定数イテレータを返します。このようなイテレータは別個のクラスであるため、実際には暗黙的にconstバージョンに変換することはできません。

代わりに、2つのイテレーターコンストラクターを使用します。

vector<int> copy_vec(vec.begin(), vec.end());

于 2011-11-10T05:39:35.767 に答える
0

ここでの問題は、std::copyが3つのパラメーターを取るように宣言されていることだと思います。

最初の2つは同じタイプであり、( const_iterator, vec.end () )-を渡します。vec.end()は非定数イテレータを返します(vecは非定数ベクトルであるため)。これにより、コンパイラはstd::copyのテンプレートを拒否します。

このような機能がある場合:

void doit ( const std::vector<int> &vec, std::vector<int> &out ) {
    std::vector<int>::const_iterator i = vec.begin();
    std::copy(i,vec.end(),back_inserter(out));
    }

次に、vec.end()がconst_iteratorを返すため、コンパイルして正常に動作します。または、C ++ 11を使用している場合は、vec.cend()を呼び出してconst_iteratorを取得できます。

于 2011-11-10T05:25:00.593 に答える