tags:

views:

78

answers:

2

Hi,

I have a very silly problem with the code shown below. The goal is to increment multiple counters at once, and have their value printed after being processed by a provided functor.

However g++ complains :

test.hpp:32: error: expected `;' before 'it' "

I tried to add some typedef, but the error message remains. Here is the code (simplified version of a bigger bunch of code)

#include <vector>
#include <iostream>

template <class F>
class Counter
{
    public:
    Counter();
    void increment(int amount);
    private:
    F calc;
    int current_amount;
};

template <class F>
void Counter<F>::increment(int amount)
{
  current_amount += amount;
  std::cout << F(amount) << "\n";
}

template <class F>
class CounterBattery
{
    public:
      CounterBattery();
      void incrementAll(int amount);
    private:
      std::vector<Counter<F> > counters;
};

template <class F>
void CounterBattery<F>::incrementAll(int amount)
{
  for (std::vector<Counter<F> >::iterator it = counters.begin() ; it != counters.end() ; it++) // fails to compile here
    it->increment(amount);
}

I do not understand what i am doing wrong with templates here.

Thanks for any help you could provide

+1  A: 

I think it might be related with std::vector<Counter<F> >::iterator being a dependent name, try to substitute it with
typename std::vector<Counter<F> >::iterator.
That way the compiler will ignore it till it is actually instantiating the template with a given F.

Here a link for dependent names in C++

EDIT: following jalf answer this link explains that if we specify typename the compiler will not confuse the name with a variable and thats the reason why it gets postponed, without the disambiguation it'll think its a var ans try to resolve it at that point.

Arkaitz Jimenez
Correct solution, but your explanation is wrong. `typename` doesn't affect *when* the template is instantiated. It just tells the compiler to assume `iterator` to be a type, rather than a value.
jalf
I didn't say it will affect to the template instantiation, I said it will postpone that type identification till the template is being instantiated, which I believe is technically correct.
Arkaitz Jimenez
Thanks for the answer, it worked perfectly. And thanks for the links too !
tiredOfCpp
It still doesn't postpone anything. It just makes a different decision when parsing it. Instead of assuming it to be a value, it asssumes it to be a type. But the decision is still taken at the same time, it's not delayed in any way.
jalf
+4  A: 

insert typename here:

for (typename std::vector<Counter<F> >::iterator it = counters.begin() ;
catwalk