Interchange of raw pointers and iterators


I want to declare and implement a function that takes as parameters either pointer or iterators. That is to say something like

void run_through(const Itr& begin, const Itr& end)
  for (Itr it = begin; it != end; ++it)
    std::cout << *it << " ";

And I want this to be callable with either an iterator or a pointer. That is to say something like.

int main(int, char**)
  int a[] = {3, 1, 4, 1, 5, 9};
  std::vector<int> A(a, a+6);
  std::set<int> B(a, a+6);

  run_through(a, a+6);
  run_through(A.begin(), A.end());
  run_through(B.begin(), B.end());

  return 0;

What I'm wondering is if I can declare run_through without any template parameters and have the implementation of run_through in a separate .cpp file.

I'm pretty sure you can't implement a function that takes either pointers or iterators without using templates. While pointers and iterators are essentially implementing the same concept, they are not types where one degrades into another one like the C array to pointer degradation.

The clean solution thus is indeed to use a single template function, for example in C++98:

template<typename forward_itr>
void run_through(forward_itr begin, forward_itr end)
  for (forward_itr it = begin; it != end; ++it)
    std::cout << *it << " ";

You can manually specialize a function template, which is what you'd have to do to have the function implementation in a separate source file, however my recommendation would be to put the whole function into a header file and let the compiler deal with it. Modern compilers and linker are pretty good at dealing with this scenario and the avoidance of possible code duplication.