adelbertc
adelbertc

Reputation: 7320

Template function with iterators

I've been trying to do Ex. 10-02 in Accelerated C++, and it was giving me errors and I eventually kept "simplifying" my program until I got to this point, and even still it wouldn't compile (via g++) giving me the error:

test.cpp: In function ‘int main()’:
test.cpp:22: error: no matching function for call to ‘dumb(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >)’

Here's my program:

#include <algorithm>
#include <iostream>
#include <vector>

using std::cout;    using std::endl;
using std::vector;

template <class Ran, class T> T dumb(Ran begin, Ran end)
{
    return *begin;
}

int main()
{
    vector<int> myVector;
    for (int i = 1; i <= 9; ++i)
        myVector.push_back(i);

    int d = dumb(myVector.begin(), myVector.end());
    cout << "Value = " << d << endl;
    return 0;
}

What's causing this error?

Upvotes: 2

Views: 662

Answers (2)

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

The compiler cannot infer the return-type here. Actually there is no need to make the return-type a template-parameter here:

template <class Ran> typename Ran::value_type dumb(Ran begin, Ran end)
{
    return *begin;
}

Upvotes: 5

iammilind
iammilind

Reputation: 69988

The problem is the prototype of your function:

template <class Ran, class T> T dumb(Ran begin, Ran end)

When using templates, return type which is dependent type (here T), cannot be deduced implicitly.

So your re-designed function should be like this:

template <class T, class Ran>
          // ^^^^^ 'T' is coming before 'Ran'
T dumb(Ran begin, Ran end)
{
  return *begin;
}

and it should be called as,

int d = dumb<int>(myVector.begin(), myVector.end());
             ^^^^

So we have done 2 changes:

  1. The type which has to be explicitly mentioned (i.e. T=int) is coming 1st
  2. Calling the dumb<> with explicit mention of int, so that return type is deducible

[Note: This solution is very generic for your understanding. As mentioned in @Bjorn's answer, for vector<> the type can be deduced automatically using ::value_type.]

Upvotes: 1

Related Questions