Вызов функции изнутри boost :: phoenix :: lambda

Я пытаюсь использовать boost::phoenix эмулировать лямбда-выражения C ++ на более старом компиляторе, в котором отсутствует поддержка C ++ 11, и я не могу вызвать простую функцию из лямбда-выражения.

Версия C ++ 11:

[](unsigned a) { foo( a ); }( 12678u );   // calls foo( 12678u )

Мой Лямбда-код Феникса выглядит следующим образом:

#include <cstdint>
#include <iostream>
#include <boost/phoenix.hpp>

namespace ph = boost::phoenix;
using ph::local_names::_a;
using ph::placeholders::arg1;

void foo( uint32_t val )
{
std::cout << "\t" << __func__ << "( " << val << " ) called...\n";
}

int main()
{
auto myLambda = ph::lambda( _a = arg1 )
[
foo( _a )
//std::cout << ph::val( "Called with: " ) << _a << ph::val( "\n" )
]( 567u );

myLambda();

return 0;
}

Это приводит к следующей ошибке компилятора:

lambda-ex.cpp: In function ‘int main()’:
lambda-ex.cpp:18:19: error: cannot convert ‘const _a_type {aka const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::local<boost::phoenix::local_names::_a_key> >, 0l> >}’ to ‘uint32_t {aka unsigned int}’ for argument ‘1’ to ‘void foo(uint32_t)’ lambda-ex.cpp:20:15: error: unable to deduce ‘auto’ from ‘<expression error>’

Как вызвать функцию из лямбда-выражения Феникса?

Я надеюсь, что смогу использовать phoneix::lambdas так же, как я использовал лямбды C ++ 11 в прошлом, например:

auto lambda1 = [&]( uint32_t arg )
{
func1( "Some Stuff", arg );
func2( "Some More Stuff", aValueFromLocalScope, arg );
func3( "Some Stuff", anotherValueFromLocalScope, arg );
};

someFuncImpl( aParam, lambda1 );

4

Решение

ph::lambda это неправильный инструмент для этой работы (ph::lambda инструмент для создания вложенных лямбда-выражений внутри выражения феникса) Феникс выражения уже функции, поэтому все, что вам нужно сделать, — это найти способ вызова функций с помощью выражений феникса (bind), найти способ выполнения нескольких операций в последовательности (operator,) и найти способ введения локальных переменных (let). Соединение всего этого дает:

#include <cstdint>
#include <iostream>
#include <boost/phoenix.hpp>

namespace ph = boost::phoenix;
using ph::local_names::_a;
using ph::placeholders::arg1;

#define FOO(name) void name( uint32_t val ) {\
std::cout << "\t" << __func__ << "( " << val << " ) called...\n";\
}
FOO(foo)
FOO(bar)
FOO(baz)

int main()
{
auto&& myLambda = ph::let(_a = arg1)
[
ph::bind(foo, _a),
ph::bind(bar, _a),
ph::bind(baz, _a)
];

myLambda(342);

return 0;
}
6

Другие решения

Неважно, если ваш пример тривиален или нет. Для вызова функций не-Phoenix необходимо использовать phoenix::bind, Период.

Лямбды в стиле феникса наиболее эффективно используются для простых выражений, основанных на перегрузке операторов. Вызов произвольных функций будет выглядеть ужасно.

C ++ 11 не добавляет лямбды в качестве языковой функции, потому что это было весело. Они сделали это, потому что различные библиотечные решения были в некотором роде неадекватными. Вы нашли один из недостатков Феникса.

4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector