Вы можете использовать обычный набор операторов для формирования выражений. Примеры:
arg1 * arg1
ref(x) = arg1 + ref(z)
arg1 = arg2 + (3 * arg3)
ref(x) = arg1[arg2]
Обратите внимание на выражение 3 * arg3
. Это выражение на самом деле является краткосрочным эквивалентом: val(3) * arg3
. В большинстве случаев, как и выше, вы можете избежать его. Но в некоторых случаях вам придется явно обернуть свои ценности в val
. Правила большого пальца:
- В бинарном выражении (например,
3 * arg3
), по крайней мере, одна из операнд должна быть феникс примитивной или экспрессией.
- В неарочном выражении (например,
arg1++
) один операнд должен быть феникс примитивным или выражением.
Если эти основные правила не соблюдаются, результат либо является ошибкой, либо немедленно оценивается. Некоторые примеры:
ref(x) = 123
x = 123
ref(x)[0]
x[0]
ref(x)[ref(i)]
ref(x)[i]
x[ref(i)]
ref(x[ref(i)])
Почему последние два выражения являются незаконными? Хотя оператор[]
выглядит так же, как бинарный оператор, как оператор=
над ним; разница в том, что первый должен быть членом (т.е. x
должен иметь оператор[]
, который принимает феникс примитивный или экспрессию в качестве своего аргумента). Это, скорее всего, не так.
Мы накрыли достаточно оснований, чтобы показать реальный мировой пример. Мы хотим найти первый нечетный номер в контейнере STL. Обычно мы используем фанктор (объект функции) или указатель функции и передаем это в STL's find_if
родовая функция:
Написать функцию:
bool
is_odd(int arg1)
{
return arg1 % 2 == 1;
}
Передайте указателю на функцию STL's find_if
алгоритм:
std::find_if(c.begin(), c.end(), &is_odd)
Используя Феникс, то же самое можно достичь непосредственно с однолинейным:
std::find_if(c.begin(), c.end(), arg1 % 2 == 1)
Выражение arg1 % 2 == 1
автоматически создает фанктор с ожидаемым поведением. В FP эта неназванная функция называется функцией lambda. В отличие от версии указателя функции, которая является мономорфной (ожидается и работает только с аргументом фиксированного типа int), версия Феникса полностью полиморфна и работает с любым контейнером (внутренний, большой и т.д.) до тех пор, пока его элементы могут обрабатывать выражение arg1 % 2 == 1.
(См. find_if.cpp)