views:

197

answers:

3

I am trying to use std::for_each to output the contents of vectors, which may contain different types. So I wrote a generic output function like so:

template<typename T> void output(const T& val)
{
    cout << val << endl;
}

which I would like to use with:

std::for_each(vec_out.begin(), vec_out.end(), output);

but the compiler complains with "could not deduce template argument" in the for_each statement. Also complains with "A function template cannot be an argument to another function template".

Is this not possible? I would have thought the compiler would know the type of vec_out (it's vector) and so should instantiate the function "output(const double& val)"?

If this doesn't work how can I get similar STL functionality without writing manual loops?

I am quite new to C++ and still learning the ropes :-)

+6  A: 

You have to pass an instantiation of the template. Something like output<int> if your vector is vector of integers.

For example:

template<typename T> void output(const T& val)
{
    cout << val << endl;
}



void main(int argc,char *argv[])
{
    std::vector<int> vec_out;
    std::for_each(vec_out.begin(), vec_out.end(), output<int>);
}
Naveen
Great, this works perfectly. I feel a bit stupid though.
20th Century Boy
`void` is not a valid return type for main.
dirkgently
+8  A: 

Try:

std::for_each(vec_out.begin(), vec_out.end(), output<T>);

where vec_out is a container (vector) of type T.

Note: The for_each algorithm expects an unary functor for its last argument. See the link for an example using functors.

dirkgently
Thanks, I was being forgetful and leaving out the <T> bit. Doh!
20th Century Boy
+4  A: 

I'd just like to add to the correct answers: the compiler can deduce the type if you wrap up your template function in a function object (aka functor):

struct OutputFunctor
{
  template <typename T>
  void operator()(const T& val) const { output(val); }
};

void test()
{
  std::vector<int> ints;
  std::vector<float> floats;

  std::for_each(ints.begin(), ints.end(), OutputFunctor());
  std::for_each(floats.begin(), floats.end(), OutputFunctor());
}
James Hopkin
I like this too! Thanks!
20th Century Boy