-1
template<class T>
map<T,int> counter(vector<T> a)
{
    map<T,int> b;
    pair<map<T,int>::iterator ,bool> pos; //This line shows compiler message
    for(int i=0;i<a.size();++i)
    {
        pos=b.insert(make_pair(a[i],1));
        if(!(pos.second))
        {
            b[pos.first -> first]++;
        }
    }
    return b;
}

This is code using templates.

map<int,int> counter(vector<int> a)
{
    map<int,int> b;
    pair<map<int,int>::iterator ,bool> pos;
    for(int i=0;i<a.size();++i)
    {
        pos=b.insert(make_pair(a[i],1));
        if(!(pos.second))
        {
            b[pos.first -> first]++;
        }
    }
    return b;
}

This is the function if I rewrite for integers alone. Integers code is working fine and first one is not. Can you explain me why it is happening and How can I modify it so I works for every data type?

Vardra
  • 1
  • 1
    Without seeing what errors you get (when posting questions about build error always include the full build log, complete and unedited), but my guess is that you should read [Where and why do I have to put the “template” and “typename” keywords?](http://stackoverflow.com/questions/7923369/when-is-the-typename-keyword-necessary) – Some programmer dude Dec 11 '15 at 08:49

2 Answers2

2

When you say "the first isn't working fine" are you implying that it doesn't compile due to some funky error about iterator? Inside a template dependent names have to be marked as types using typename:

pair<map<T, int>::iterator, bool> pos;

The name iterator is a nested name inside std::map<T, int>. You'd just use

pair<typename map<T, int>::iterator, bool> pos;

instead.

Personally, I'd be inclined to entirely side-step the issue an implement the function like this:

template<class T>
std::map<T, int> counter(std::vector<T> const& a)
{
    std::map<T, int> result;
    std::for_each(a.begin(), a.end(), [&](T const& value){ ++result[value]; });
    return result;
}

This implementation takes advantage of the fact that operator[]() inserts new elements with a value initialized value (i.e., using T()). Put differently, when there is on object inside the map, it will return a reference to a zero initialized int.

Dietmar Kühl
  • 141,209
  • 12
  • 196
  • 356
0

map<T,int>::iterator is a dependent name, i.e. it is dependent on a template parameter. You need to tell the compiler that it always names a type so that it can be parsed correctly:

pair<typename map<T,int>::iterator ,bool> pos;
//   ^^^^^^^^

See this question for more information about the typename keyword and when you need to use it.

Community
  • 1
  • 1
TartanLlama
  • 59,364
  • 11
  • 141
  • 183