Search code examples
c++templatesforeachstlfunctor

passing template function to std::for_each


I am trying to write a simple template function that prints every element of some container, without using for loops. So far, I have

#include <iostream>
#include <vector>
#include <algorithm>

template <typename T> void print_with_space(T x){
  std::cout << x << ' ';
}

template <typename T> void print_all(T beg, T end){
  std::for_each(beg, end, print_with_space<int>);
  std::cout << '\n';
}

int main(){
  int a[] = {1, 2, 3};
  std::vector<int> v(a, a+3);
  print_all(v.begin(), v.end());
  return 0;
}

The code compiles and runs, but only because I put print_with_space<int> inside the implementation of print_all. I would like to just have print_with_space there for obvious reasons, but then the code doesn't compile. How do I do this?


Solution

  • You can use:

    std::for_each(beg, end, [](const typename T::value_type& value) {
        print_with_space(value);
    });
    

    T is of type std::vector<>::iterator, which is a RandomAccessIterator. Every RandomAcessIterator has a underlying type, which is exposed by value_type.

    So, if you pass std::vector<int>::iterator, std::vector<int>::iterator::value_type would be an int.

    Now that you have the type, you can make a lambda, which will get executed for every iteration.


    In C++14, you can even do:

    //'auto' automatically deduces the type for you
    std::for_each(beg, end, [](const auto& value) {
        print_with_space(value);
    });