Моделирование вложенных функций в C ++
-
27-10-2019 - |
Вопрос
В C следующий код работает в GCC.
int foo( int foo_var )
{
/*code*/
int bar( int bar_var )
{
/*code*/
return bar_var;
}
return bar(foo_var);
}
Как я могу добиться той же функциональности вложенных функций в C ++ с помощью компилятора GCC? Не возражайте, если это кажется новичком. Я новичок на этом сайте.
Решение
Превратить свою функцию в функтор как Херб Саттер предлагает в этой статье
Другие советы
Локальные функции не допускаются в C ++, но локальные классы разрешены, и функции разрешены в локальных классах. Так:
int foo( int foo_var )
{
/*code*/
struct local
{
static int bar( int bar_var )
{
/*code*/
return bar_var;
}
};
return local::bar(foo_var);
}
В C ++ 0x у вас также будет возможность создать функтор с использованием синтаксиса Lambda. Это немного сложнее в C ++ 03, но все же неплохо, если вам не нужно захватывать переменные:
int foo( int foo_var )
{
/*code*/
struct bar_functor
{
int operator()( int bar_var )
{
/*code*/
return bar_var;
}
} bar;
return bar(foo_var);
}
Используйте местный функтор
#define lambda(return_type, function_body) \
struct { return_type operator () function_body }
int main ()
{
lambda(int, (int x, int y) { return x > y ? x : y; } ) maxFunc;
int m = maxFunc(1,2); //=> 2
...
}
Конструкция, которая ближе всего к вложенным функциям, - это C ++ 11 Lambda.
void SomeFunction(int x)
{
int var = 2;
auto lambda = [&] (int param) -> int { return var + param; };
printf("var + x = %d\n", lambda(x));
}
Lamdas позволяют использовать переменные из внешней области ([&] определяет для автоматического захвата всех переменных из внешней области по ссылке). Лямбда, которая не использует каких -либо переменных из внешней области (использование []), может быть преобразована в указатель функции того же типа и, таким образом, может быть передана функциям, принимающим указатель функции.
Вы можете попробовать использовать Boost :: Phoenix (v2 - это подпакера духа, V3 находится в SVN/Trunk, поскольку он является собственным пакетом и должен быть в 1.47)
#include <boost/spirit/include/phoenix.hpp>
#include <boost/function.hpp>
using namespace boost::phoenix::arg_names;
int foo( int foo_var )
{
/*code*/
boost::function<int(int)> bar = _1 + 5;
return bar(foo_var);
}
int main() {
return foo(1);
}
В C ++ вы можете достичь того же эффекта другими возможными средствами. Нет прямых вложенных функций. Две полезные ссылки:
http://www.respower.com/~earlye/programming/19990916.001.htm
AFAIK, вложенные функции не допускаются в C ++.
Я знаю, что эта ветка старая. Но решением C ++ 11 было бы написать лямбдас и позвонить им всякий раз, когда захотел