ошибка времени компиляции в отношении реализации функции шаблона - PullRequest
0 голосов
/ 01 октября 2011

Я пытаюсь написать контейнерный класс с итератором. Это мой класс:

template <class T>
class C{
 private:
  T* v;
  int MAX_SIZE;
  int i;
 public:
  C (int size){
   MAX_SIZE = size;
   v = new T (MAX_SIZE);
   i = 0;
  }

 ~C(){ delete v; }

  class iterator{
   private:
    T* v;
   public:
    iterator(T* ip){ v = ip; }

    void operator++ (){ ++v; }
    void operator-- (){ --v; }
    T    operator*  () { return *v; }
    bool operator!= (const iterator & it) { return v != it.v; }
 };

 iterator begin(){ return iterator (v); }
 iterator end()  { return iterator (&v[MAX_SIZE]); }

 void push_back (T e){
   if (i == MAX_SIZE) throw MaxSizeReached();
   v[i] = e;  
   ++i;
 }

 class MaxSizeReached{};
};

template <class T>
void print(typename C<T>::iterator & start, typename C<T>::iterator & end){
 for (typename C<T>::iterator s (start), e (end); s != e; ++s){
   std::cout << *s << '\n';
 }
}

int main(){
 C<int> ic (3);
 C<float> fc (4);
 C<char> cc (3);

 ic.push_back (56);
 ic.push_back (76);
 ic.push_back (88);

 print<int>(ic.begin(), ic.end());

 return 0;
}

g ++ 4.5 выдает эту ошибку:

templatizedCustomIterator.c++: In function ‘int main()’:
templatizedCustomIterator.c++:71:35: error: no matching function for call to ‘print(C<int>::iterator, C<int>::iterator)

Что неверно - определение print () или вызов?

Ответы [ 2 ]

3 голосов
/ 01 октября 2011

Посмотрите на шаблон функции:

template<T>
void print(typename C<T>::iterator & start, typename C<T>::iterator & end);

И ваше использование:

 print(ic.begin(), ic.end());

Итак, проблема в том, что T не может быть выведено из аргумента функции.Стандарт называет это не выводимым контекстом .Здесь я подробно объяснил аналогичный вопрос, прочитайте это:

Теперь вопрос в том,как бы вы реализовали шаблон функции?Итак, вот одно хорошее решение:

template <class FwdIterator>
void print(FwdIterator start, FwdIterator end)
{
  for ( ;  start != end;  ++start)
  {
     std::cout << *start << '\n';
  }
}

Если вы передадите третий аргумент как:

template <class FwdIterator>
void print(FwdIterator start, FwdIterator end, std::ostream &out)
{
  for ( ;  start != end;  ++start)
  {
     out << *start << '\n';
  }
}

, то вы также можете использовать его для печати в файл:

 print(ic.begin(), ic.end(), std::cout); //print to console


 std::ofstream file("file.txt")
 print(ic.begin(), ic.end(), file); //print to file
0 голосов
/ 01 октября 2011

Функция print должна принимать параметры как ссылки const, в противном случае ее нельзя использовать с временными значениями, такими как значения, возвращаемые begin() и end():

template <class T>
void print(const typename C<T>::iterator & start, const typename C<T>::iterator & end){
   ...
}
...