1

I've always found C++ templates inscrutable, and C++ error messages more so. I want to understand it, rather than always feeling confused. Here's the latest bizarre experience:

error: conversion from ‘<unresolved overloaded function type>’ to non-scalar type ‘std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}’ requested

This doozy comes from the following code:

#include <iostream>
#include <vector>

using namespace std;

template <typename T>
void printVector(const vector<T>& v) {
    for (typename vector<T>::iterator iter = v.begin; iter != v.end; iter++) {
        cout << *iter << endl;
    }
}

int main() {
    vector<int> v{1, 2, 3};
    printVector(v);
    return 0;
}

It has no problem iterating over the vector if I use a C++11 range-based loop. I want to learn how to do it using iterators.

Can someone explain what the error means and how to fix it?

It would also be wonderful if I could get a recommendation of a book that explains templates well.

marshallm
  • 1,115
  • 1
  • 8
  • 9

3 Answers3

3

See the error message carefully. It says you're trying to convert a function to iterator. You should call them by adding ().

Change

for (typename vector<T>::iterator iter = v.begin; iter != v.end; iter++) {

to

for (typename vector<T>::iterator iter = v.begin(); iter != v.end(); iter++) {
                                                ~~               ~~

For C++ books, The Definitive C++ Book Guide and List

Community
  • 1
  • 1
songyuanyao
  • 147,421
  • 15
  • 261
  • 354
2

You're missing the parentheses from begin and end and since you're passing the vector by const reference you'll need a const_iterator.

template <typename T>
void printVector(const vector<T>& v) {
    for (typename vector<T>::const_iterator iter = v.begin(); iter != v.end(); iter++) {
                             ^^^^^^^^^^^^^^               ^^                ^^
        cout << *iter << endl;
    }
}

Better yet use a ranged base for:

template <typename T>
void printVector(const vector<T>& v) {
    for(auto &&e : v) {
        cout << e << endl;
    }
}
101010
  • 39,010
  • 10
  • 84
  • 149
0

std::vector<T>::begin and ::end are functions; you need to call them:

for (typename vector<T>::iterator iter = v.begin(); iter != v.end(); iter++) {
//                                              ^^               ^^
    cout << *iter << endl;
}

Additionally, you are trying to convert a const iterator to a non-const one. You need to use vector<T>::const_iterator, or, better yet, auto.

TartanLlama
  • 59,364
  • 11
  • 141
  • 183