【问题标题】:Question on operator+ overload of random access iterator, in template关于模板中随机访问迭代器的运算符+重载的问题
【发布时间】:2011-07-22 16:32:43
【问题描述】:

我想在列表类中重载迭代器的“+”运算符,比如

list<double>::iterator operator+(const list<double>::iterator& it, int n)

这很好用。但是,当我尝试将其实现为模板时,例如

template<class T>
typename list<T>::iterator operator+(const typename list<T>::iterator& it, int n)

我收到了类似的错误消息,

no match for 'operator+' in 'it + small_index'

不知道是什么原因……

代码附在下面,

#include<iostream>
#include<list>
using namespace std;

template<class T>
ostream& operator<< (ostream& os, const list<T>& l)
{
  typename list<T>::const_iterator i = l.begin();
  for (;i!=--l.end();i++)
    os<<*i<<";";
  os<<*i<<endl;
  return os;
}

template<class T> //this is where it goes WRONG.
                  //If don't use template, delete "typename", T->double, runs well
typename list<T>::iterator operator+(const typename list<T>::iterator& it, int n)
{
  typename list<double>::iterator temp=it;
  for(int i=0; i<n; i++)
    temp++;
  return temp;
}

template <class T>
void small_sort(list<T>& l)
{
  int n = l.size();
  typename list<T>::iterator it = l.begin();
  for(int i=0; i<n-1; i++)
    {
      //Find index of next smallest value
      int small_index = i;
      for(int j=i+1; j<n; j++)
    {
      if(*(it+j)<*(it+small_index)) small_index=j;
    }
      //Swap next smallest into place
      double temp = *(it+i);
      *(it+i) = *(it+small_index);
      *(it+small_index)=temp;
    }
}

int main()
{
  list<double> l;
  l.push_back(6);
  l.push_back(1);
  l.push_back(3);
  l.push_back(2);
  l.push_back(4);
  l.push_back(5);
  l.push_back(0);

  cout<<"=============sort the list=============="<<endl;
  small_sort(l);
  cout<<l;
  return 0;
}

【问题讨论】:

  • 为什么不用std::advance 而不是重写呢?
  • 标题很容易误导,因为列表迭代器不是随机访问的。为列表迭代器提供operator+ 会鼓励使用效率低下的算法(这就是标准没有这样的运算符的原因)。

标签: c++ templates iterator overloading operator-keyword


【解决方案1】:

问题在于该论点在这种情况下是不可推导出的。

template<class T>
typename list<T>::iterator operator+(const typename list<T>::iterator& it, int n);

当您在那里使用迭代器时,编译器必须生成具有任何给定类型的 list 的所有可能实例化,并尝试将内部类型 iterator 与您传递的参数匹配,注意集合一旦您将模板添加到组合中,所有类型实际上是无限的,因为您可以使用相同模板的实例化来实例化模板ad infinitum

我建议您完全避免这个问题并使用std::advance,这是推进迭代器的惯用方式。

【讨论】:

    【解决方案2】:

    你应该看看是否可以使用标准算法std::advance(it, n)。它在&lt;iterator&gt; 中定义。它为任何合适的迭代器做“正确的事情”。

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多