2011-10-04 66 views
0

我有一個模板化的Stack類,內部實現了vector。模板類上的C++操作符重載

這是我(簡化)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 

我不知道錯誤信息的含義是什麼。

在運算符+函數中,我使用了相同的方式來獲取printAll()中的迭代器,但它在operator +函數內部不能正常工作。 我知道我可以避免在運算符+函數中使用迭代器,但我只是好奇如何解決這個問題。

回答

5

使用const_iterator代替iterator

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

因爲s1是一個const對象。因此s1.items也將是const對象,這意味着s1.items.begin()將返回const_iterator,而不是非const iterator


更好地執行運營商+()

可以提高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的問題。


更多更好的執行操作的+()

如果您接受值的第一個參數,而不是常引用,那麼就更好了:

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的局部變量。您只需將s2添加到s1並返回s1即可。

+1

感謝您的幫助! – Hery

3

您不能將常量迭代器(s2.items.begin())分配給非常量迭代器。 使用

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

謝謝你的回答,但我必須把接受的答案給予納瓦茲,因爲他回答了1分鐘快哈哈哈... – Hery

+0

沒問題,這就是如何運作 – stijn