Reputation: 191
I realise there are a lot of similar questions, but I couldn't find any that solves my problem (read: I did not truly understood the answers so that I could apply it to my case)
I have the following function:
void printVariable(map<string, bool*>::iterator it)
{
cout << it->first << " " << *(it->second) << endl;
}
Now If i have a map<string, bool*> mapping
I can do the following: printVariable(mapping.begin());
This works, now I also have a a map<string, int*>
and want to be able to do the same, so I figured I change the printVariable function:
template <typename T>
void printVariable(map<string, T*>::iterator it)
{
cout << it->first << " " << *(it->second) << endl;
}
However this gives compile errors (gcc):
error: variable or field 'printVariable' declared void
error: expected ')' before 'it'
I guess I can work around this pretty easy by overloading the function. But I'd like to know why the above is not working.
Edit2: removed text claiming a right solution was wrong
Upvotes: 0
Views: 86
Reputation: 476940
You have to say typename
to disambiguate the dependent name:
template <typename T>
void printVariable(typename map<string, T*>::iterator it)
// ^^^^^^^^
However, note that this is not a deducible context, so this form isn't terribly convenient.
Better yet, just make the entire iterator a template parameter:
template <typename Iter>
void printVariable(Iter it)
{ /* ... */ }
That way, you also capture maps with non-standard comparators or allocators, and unordered maps, etc. etc.
Here's a simple thought experiment for why you don't have a deducible context in the first situation: How should T
be deduced in the following call of foo
?
template <typename T> void foo(typename Bar<T>::type);
template <typename T> struct Bar { typedef char type; };
template <> struct Bar<int> { typedef int type; };
template <> struct Bar<double> { typedef int type; };
foo(10); // What is T?
Upvotes: 5