Как использовать boost::fusion::transform для гетерогенных контейнеров?

Boost.org пример для fusion::transform выглядит следующим образом:

struct triple
{
    typedef int result_type;

    int operator()(int t) const
    {
        return t * 3;
    };
};
// ...
assert(transform(make_vector(1,2,3), triple()) == make_vector(3,6,9));

И все же я не «понимаю». Вектор в их примере содержит элементы одного и того же типа, но основным моментом использования слияния являются контейнеры разнородных типов. Что, если бы они использовали make_vector(1, 'a', "howdy") вместо этого?

int operator()(int t)
нужно будет стать
template<typename T> T& operator()(T& const t)

Но как мне написать result_type? template<typename T> typedef T& result_type определенно недопустимый синтаксис, и даже если бы он был, это не имело бы смысла, потому что оно не привязано к функции.


person Kyle    schedule 15.05.2010    source источник
comment
Вы уверены, что result_type требуется, а не потому, что парню нравится вставлять его туда? В приведенном выше примере он, кажется, использует примитивную форму decltype для формирования типа результата.   -  person Puppy    schedule 16.05.2010
comment
угу, ты прав, это не обязательно. Спасибо. Я собираюсь опубликовать новый вопрос с просьбой найти реальное руководство по boost::fusion, эта документация на boost.org едва ли на шаг выше чтения самого кода. Гррр.   -  person Kyle    schedule 16.05.2010


Ответы (2)


Обычно fusion::transform используется с шаблонным (или, как показано выше, иначе перегруженным) оператором функции:

struct triple 
{ 
    template <typename Sig>
    struct result;

    template <typename This, typename T>
    struct result<This(T)>
    {
        typedef /*...figure out return type...*/ type;
    };

    template <typename T> 
    typename result<triple(T)>::type 
    operator()(T t) const 
    { 
        return 3*t;    // relies on existing operator*() for 'T'
    }
}; 

Кроме того, дополнительными источниками информации о Fusion являются примеры и тестовый каталог, где вы можете найти демонстрации некоторых методов.

С уважением Хартмут

person hkaiser    schedule 16.05.2010
comment
В частности, ‹boost›/libs/fusion/test/algorithm/transform.cpp — я понятия не имел о существовании этих тестовых файлов. Спасибо! - person Kyle; 17.05.2010
comment
boost::fusion::transform кажется неудачным, когда F является лямбдой С++. Это известная проблема или я не могу ее правильно вызвать? - person Johannes Schaub - litb; 18.09.2016

Вы пытались перегрузить оператор вызова ()?

struct triple
{

    int operator()(int t) const
    {
        return t * 3;
    };
    int operator()(string t) const
    {
        return t + t + t;
    };
};
person Vicente Botet Escriba    schedule 16.05.2010