tags:

views:

127

answers:

3
+3  Q: 

Template problem.

Why on earth I can do this:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

void myfunction (int i) {
  cout << " " << i;
}

int main () {
  vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myfunction);//<-------See below
return 0;
}

but can't do this:

template<class T>
    void myfunction (T i) {
          cout << " " << i;
        }

I suspect that it has something to do with args deduction but it is so infuriating that "regular" fnc is accepted and template isn't.

+5  A: 

You can't pass templates to the third argument of for_each. You have to pass an instance that is callable via operator()(). In this case, you can instantiate the function template by providing all the template parameters of the function:

 std::for_each(myvector.begin(), myvector.end(), &myfunction<int>);

On a side note, you should really avoid using namespace std as it introduces many names that can clash with your identifiers. Also, you should use the & syntax to make it clear that you're passing a function pointer.

In silico
+1 for the style advice.
Michael Aaron Safyan
+9  A: 

The problem is that you cannot create a pointer to a template function. You should be able to create a pointer to an instantiated template function though. I haven't tried this but the following should work:

for_each (myvector.begin(), myvector.end(), myfunction<int>)
dark_charlie
+5  A: 

Because compiler cannot convert a template into a predicate implicitly. You have to explicitly state what function to call:

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

using namespace std;

template <typename T>
void myfunction (T i)
{
    cout << " " << i;
}

int main () {
  vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myfunction<int>);
  cout << endl;
}

Alternatively, you can write a predicate like this:

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

using namespace std;

struct MyPredicate {
    template <typename T>
    void operator () (T i)
    {
        cout << " " << i;
    }
};

int main () {
  vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), MyPredicate ());
  cout << endl;
}
Vlad Lazarenko