There is no way for the compiler to know which printItem
specialisation you wanted, with the information available to it according to the standard at that point.
So, this syntax is not available here.
This is what you need:
for_each(t.begin(), t.end(), printItem<typename T::value_type>);
Being able to do this kind of thing is exactly why containers are required to define type aliases like value_type
; you end up needing them all over the place.
A limitation in the language? Perhaps. But it does help avoid corner cases.
Having to use typename
here certainly is an annoyance, though.
Your code, to be honest, would be a lot easier and clearer if you just used a loop:
for (const auto& item : t)
printItem(item);
In the time of ranged-for and all that lovely stuff, for_each
is not all that useful for common cases any more.
Also, take the arguments by reference-to-const
, and remove the erroneous dereference. I'll also remove the repeated std::endl
, which is performing stream flushing you don't need.
template <class T>
void printItem(const T& t)
{
std::cout << t << '\n';
}
template <class T>
void printVector(const T& t)
{
for (const auto& item : t)
printItem(t);
}
int main()
{
std::vector<std::string> vs = {"word1", "word2"};
printVector(vs);
}
Finally, it's a good idea to let functions like printItem
take a reference to the stream you want to use, so that you could pick (say) a std::stringstream
rather than only std::cout
.