【问题标题】:C++ operator overloading on templated class模板类上的 C++ 运算符重载
【发布时间】:2011-10-04 10:06:35
【问题描述】:

我有一个模板化的 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+ 函数中使用迭代器,但我只是好奇如何解决这个问题。

【问题讨论】:

    标签: c++ templates operator-overloading friend-function


    【解决方案1】:

    使用const_iterator 代替iterator

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

    因为s1 是一个常量对象。所以s1.items 也将是 const 对象,这意味着 s1.items.begin() 将返回 const_iterator,而不是非 const iterator


    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; 
    }
    

    由于第一个参数是 copy 本身,因此您无需显式创建名为 result 的局部变量。您只需将s2 添加到s1 并返回s1

    【讨论】:

      【解决方案2】:

      您不能将 const 迭代器 (s2.items.begin()) 分配给非 const 迭代器。 使用

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

      【讨论】:

      • 感谢您的回答,但我必须将接受的答案提供给 Nawaz,因为他回答的速度快了 1 分钟哈哈哈...
      猜你喜欢
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多