Reputation: 9502
Why this code does not compile:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <iostream>
using namespace std;
using namespace boost;
template <class T> // specific visitor for type printing
static void print_type(T t)
{
std::cout << typeid(T).name() << std::endl;
}
typedef mpl::vector<int, long, char*> s;
int main ()
{
mpl::for_each<s>(print_type());
}
I wonder - how to make boost mpl for_each work with free functions from same class?
Upvotes: 3
Views: 3243
Reputation: 7667
As stated you need a functor.
The code below includes an additional wrap template that allows the print functor to cope with references.
#include <iostream>
#include <typeinfo>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/placeholders.hpp>
using namespace std;
using namespace boost;
template <typename T>
struct wrap {};
struct print_type
{
template< typename T>
void operator()( wrap<T> ) const
{
cout << typeid(T).name() << "\n";
}
};
typedef mpl::vector<int, long&, char*> s;
int main ()
{
mpl::for_each<s, wrap<mpl::placeholders::_1> >(print_type());
return 0;
}
Note: this code based on examples in the book 'C++ Template Metaprogramming by David Abrahams and Aleksy Gurtovoy
Upvotes: 4
Reputation: 473437
mpl::for_each<s>(print_type());
This is wrong in a couple of ways.
First, print_type
is a function that returns void
. print_type()
is an attempt to call that function. Since it returns nothing, you can't stick its non-existent return value into something else.
Second, print_type
is a template function. You cannot call a template function without specifying the template parameters. So print_type()
is ill-formed.
Third, even mpl::for_each<s>(print_type)
doesn't work, because print_type
is not a value (nor is it convertible to a value); it is a template. You cannot pass a template as the argument of a function. That's why visitors (for many things, not just MPL) are objects, which can have template operator()
members.
Upvotes: 3