0

ベクターを使用して内部的に実装されたテンプレート化された Stack クラスがあります。

これが私の(簡略化された)TStack.hの内容です:

#include <vector>
#include <iostream>

template<typename T> class TStack;
template<typename T> TStack<T> operator+(const TStack<T> &s1, const TStack<T> &s2);

template<typename T>
class TStack {
    friend TStack<T> operator+<>(const TStack<T> &s1, const TStack<T> &s2);
    private:
        std::vector<T> items;
    public:
        void printAll() {
            std::cout << "The content of the stack is: ";
            typename std::vector<T>::iterator it;
            for(it = items.begin(); it < items.end(); it++) {
                std::cout << *it << " ";
            }
            std::cout << std::endl;
        }
};

template<typename T>
TStack<T> operator+(const TStack<T> &s1, const TStack<T> &s2) {
    TStack<T> result = s1;
    typename std::vector<T>::iterator it;
    //below is line 41
    for(it = s2.items.begin(); it < s2.items.end(); it++) {
        result.items.push_back(*it);
    }
    return result;
}

そして、これは私の(簡略化された)メインクラスです:

#include <iostream>
#include "TStack.h"

using namespace std;

int main(int argc, char *argv[]) {
    TStack<int> intStack;
    intStack.push(4);

    TStack<int> secondIntStack;
    secondIntStack.push(10);

    cout << "Addition result: " << endl;
    //below is line 27
    TStack<int> result = intStack + secondIntStack;
    result.printAll();
    return 0;
}

そして、これはコンパイル結果です:

In file included from main.cpp:2:
TStack.h: In function ‘TStack<T> operator+(const TStack<T>&, const TStack<T>&) [with T = int]’:
main.cpp:27:   instantiated from here
TStack.h:41: error: no match for ‘operator=’ in ‘it = s2->TStack<int>::items.std::vector<_Tp, _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>]()’
/usr/include/c++/4.4/bits/stl_iterator.h:669: note: candidates are: __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >& __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::operator=(const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&)
make: *** [main.exe] Error 1

エラーメッセージの意味がわかりません。

operator+ 関数では、同じ方法で printAll() 内の反復子を取得しましたが、operator+ 関数内では正しく動作しません。operator+ 関数でイテレータを使用しないようにできることはわかっていますが、これを修正する方法に興味があります。

4

2 に答える 2

5

const_iteratorの代わりに使用iterator:

typename std::vector<T>::const_iterator it;

s1const オブジェクトだからです。s1.itemsconst オブジェクトも同様です。つまり、non-const ではなくs1.items.begin()return になります。const_iteratoriterator


operator+() のより良い実装

の実装を改善できますoperator+()手動ループとpush_back関数を使用する代わりに、関数を次のように使用できますinsert

template<typename T>
TStack<T> operator+(const TStack<T> &s1, const TStack<T> &s2) {
    TStack<T> result(s1); //use direct copy-initialization
    result.insert(result.end(), s2.begin(), s2.end());
    return result;
}

コードで直面する問題を完全に回避iteratorします。


operator+() のより良い実装

const 参照の代わりに値で最初の引数を受け入れる場合は、さらに優れています。

template<typename T>
TStack<T> operator+(TStack<T> s1, const TStack<T> &s2) {
    s1.insert(s1.end(), s2.begin(), s2.end()); //s1 is a copy, after all!
    return s1; 
}

最初の引数はコピーresult自体であるため、明示的に呼び出されるローカル変数を作成する必要はありません。に追加s2s1て返すだけs1です。

于 2011-10-04T10:10:33.887 に答える
3

定数反復子 ( s2.items.begin()) を非定数反復子に割り当てることはできません。使用する

typename std::vector<T>::const_iterator it;
于 2011-10-04T10:12:01.477 に答える