Вопрос по оператору + перегрузка итератора произвольного доступа, в шаблоне - PullRequest
2 голосов
/ 22 июля 2011

Я бы хотел перегрузить оператор "+" итератора в классе списка, что-то вроде

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

Ответы [ 2 ]

5 голосов
/ 22 июля 2011

Проблема в том, что аргумент не выводится в этом контексте.

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

Когда вы используете там итератор, компилятор должен будет сгенерировать все возможные экземпляры list с любым заданным типом и попытаться сопоставить внутренний тип iterator с передаваемым аргументом, обратите внимание, что набор всех типов фактически бесконечно, когда вы добавляете шаблоны в микс, так как вы можете создать экземпляр шаблона с использованием экземпляра того же самого шаблона до бесконечности .

Я рекомендую вам полностью избежать этой проблемы и использовать std::advance, что является идиоматическим способом продвижения итератора.

1 голос
/ 22 июля 2011

Вы должны посмотреть, можно ли использовать стандартный алгоритм std::advance(it, n). Это определено в <iterator>. Это делает "правильную вещь" для любого подходящего итератора.

...