Повысьте mpl для каждой и свободных функций - PullRequest
3 голосов
/ 02 декабря 2011

Почему этот код не компилируется:

#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());
}

Интересно - как заставить boost mpl for_each работать со свободными функциями из того же класса?

Ответы [ 2 ]

4 голосов
/ 13 декабря 2011

Как уже говорилось, вам нужен функтор.

Приведенный ниже код включает дополнительный шаблон обертки, который позволяет функтору печати справляться со ссылками.

#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;
}

Примечание.на основе примеров из книги Дэвида Абрахамса и Алексея Гуртового «Шаблон метапрограммирования на С ++»

3 голосов
/ 02 декабря 2011
    mpl::for_each<s>(print_type());

Это неправильно в двух отношениях.

Во-первых, print_type - это функция, которая возвращает void. print_type() - это попытка вызвать эту функцию. Поскольку он ничего не возвращает, вы не можете вставить его несуществующее возвращаемое значение во что-то другое.

Во-вторых, print_type - это шаблон функция. Вы не можете вызвать функцию шаблона без указания параметров шаблона. Так что print_type() плохо сформирован.

В-третьих, даже mpl::for_each<s>(print_type) не работает, потому что print_type не является значением (и не может быть преобразовано в значение); это шаблон. Вы не можете передать шаблон в качестве аргумента функции. Вот почему посетители (для многих вещей, не только MPL) являются объектами, которые могут иметь шаблон operator() членов.

...