Я ожидаю, что следующий пример Boost Phoenix выражение для компиляции.
Что мне не хватает?
int plus(int a,int b)
{
return a+b;
}
void main(int argc,char** argc)
{
auto plus_1 = phx::bind(&plus,1,arg1);
auto value = phx::lambda[phx::val(plus_1)(arg1)]()(1);
std::cout << value << std::endl;
}
auto plus_1 = phx::bind(&plus,1,arg1);
После этой строки plus_1
является функциональным объектом, который занимает один int
аргумент и добавляет один к нему.
phx::lambda[plus_1(arg1)](1);
Упс. Это не сработает, потому что (как мы уже говорили выше) plus_1
является функциональным объектом, который занимает один int
аргумент и добавляет один к нему. Здесь вы пытаетесь вызвать его с arg1
,
Из вашего кода не очевидно, что вы ожидаете от него. Вы можете уточнить?
==== ==== EDIT
Я вижу, вы редактировали код в своем вопросе. Ваш код по-прежнему неверен, но по другой причине. Это:
phx::val(plus_1)(arg1)
… использования val
создать нулевую функцию, которая возвращает plus_1
унарная функция. Затем вы пытаетесь вызвать нулевую функцию с arg1
, Boom.
Вот код, который выполняет и выполняет (во что я верю) ваше намерение:
#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
using phx::arg_names::arg1;
int plus(int a,int b)
{
return a+b;
}
int main()
{
auto plus_1 = phx::bind(&plus, 1, arg1);
int value = phx::bind(phx::lambda[plus_1], arg1)(1);
std::cout << value << std::endl;
}
Первый bind
принимает двоичный файл plus
и превращает его в унарную функцию с первым аргументом, связанным с 1
, Второй bind
создает новую унарную функцию, которая эквивалентно первому, но он делает это, безопасно завершая первую функцию, используя lambda
, Почему это необходимо? Рассмотрим приведенный ниже код, который эквивалентен, но без lambda
:
// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);
Заметить, что arg1
появляется дважды. Все выражения оцениваются изнутри. Сначала мы свяжем внутренний arg1
в 1
затем оцените внутреннее bind
получая 2
, который мы затем пытаемся связать и вызвать. Это не сработает, потому что 2
не вызывается
Использование lambda
создает пространство для внутреннего arg1
так что это не жадно подставляется. Но, как я уже сказал, использование второго bind
, что вызывает необходимость lambda
, возвращает функцию, эквивалентную первой. Так что это излишне сложно. Но, возможно, это помогло вам понять bind
, lambda
и феникс прицелы.
Мне не ясно, чего вы пытаетесь достичь, используя lambda
здесь, но если вы просто хотите позвонить plus_1
с 1
(в результате чего 2
), это намного проще, чем ваша попытка:
#include <iostream>
#include <boost/phoenix.hpp>
int plus(int a, int b)
{
return a + b;
}
int main()
{
namespace phx = boost::phoenix;
auto plus_1 = phx::bind(plus, 1, phx::arg_names::arg1);
std::cout << plus_1(1) << '\n';
}
Если это не что вы пытаетесь достичь, тогда вам нужно описать то, что вы на самом деле хотите. : -]
Возможно, это может объяснить это лучше.
Феникс не магия; это прежде всего C ++. Следовательно, следует правила C ++.
phx::bind
это функция, которая возвращает объект функции, объект с перегруженным operator()
который вызывает функцию, которая была связана. Ваше первое заявление сохраняет этот объект в plus_1
,
Учитывая все это, в любой момент у тебя есть выражение plus_1(...)
, это вызов функции. Это и есть; Вы говорите, что хотите позвонить перегруженным operator()
функция на тип этого объекта, и что вы собираетесь передать некоторые значения этой функции.
Неважно, находится ли это выражение в середине []
или нет. phx::lambda
не может заставить C ++ изменить свои правила. Это не может сделать plus_1(...)
что-нибудь Другой чем немедленный вызов функции. Не может arg1
делать plus_1(...)
не немедленный вызов функции.