Возможно ли в C или С++ создать функцию внутри другого?

Вопрос:Может кто-нибудь скажет мне, возможно ли это на C или С++? void fun_a(); //int fun_b(); ... main(){ ... fun_a(); ... int fun_b(){ ... } ... } или что-то подобное, например. класс внутри функции? спасибо за ваши ответы, Лучший ответ: Ничего себе, я удивлен, что никто не сказал да! Свободные функции не могут быть вложенными, но

Вопрос:

Может кто-нибудь скажет мне, возможно ли это на C или С++?

void fun_a(); //int fun_b(); … main(){ … fun_a(); … int fun_b(){ … } … }

или что-то подобное, например. класс внутри функции?

спасибо за ваши ответы,

Лучший ответ:

Ничего себе, я удивлен, что никто не сказал да! Свободные функции не могут быть вложенными, но функторы и классы вообще могут.

void fun_a(); //int fun_b(); … main(){ … fun_a(); … struct { int operator()() { … } } fun_b; int q = fun_b(); … }

Вы можете дать функтору конструктор и передать ссылки на локальные переменные, чтобы подключить его к локальной области. В противном случае он может обращаться к другим локальным типам и статическим переменным. Однако локальные классы не могут быть аргументами для шаблонов.

Ответ №1

С++ не поддерживает вложенные функции, однако вы можете использовать что-то вроде boost:: lambda.

Ответ №2

C – Да для gcc как расширение.

С++ – Нет.

Ответ №3

Нет, но в С++ 0x вы можете http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions, что может потребоваться еще несколько лет для полной поддержки. Стандарт не является полным на момент написания этой статьи.

-edit-

Да

Если вы можете использовать MSVC 2010. Я успешно выполнил код ниже

void test() { []() { cout << «Hello functionn»; }(); auto fn = [](int x) -> int { cout << «Hello function (» << x << » :))n»; return x+1; }; auto v = fn(2); fn(v); }

Выход

Hello function Hello function (2 :)) Hello function (3 :))

(я написал >> c:devlocuniqueName.txt в разделе рабочих аргументов проекта и скопировал этот результат)

Ответ №4

вы не можете создать функцию внутри другой функции в С++.

Однако вы можете создать локальный класс-функтор:

int foo() { class bar { public: int operator()() { return 42; } }; bar b; return b(); }

в С++ 0x вы можете создать выражение лямбда:

int foo() { auto bar = []()->int{return 42;}; return bar(); } Ответ №5

Термин, который вы ищете, – это вложенная функция. Ни стандартные C, ни С++ не допускают вложенных функций, но GNU C позволяет использовать его как расширение. Вот хорошая статья статьи в википедии по этому вопросу.

Ответ №6

Clang/Apple работают над “блоками”, анонимными функциями в C!:-D

^ (void) {printf ( “hello worldn” ); }

info здесь и spec here, и ars technica имеет немного на нем

Ответ №7

Нет, и есть по крайней мере одна причина, по которой это осложнит ситуацию. Предполагается, что вложенные функции имеют доступ к охватывающей области. Это делает так, что “стек” больше не может быть представлен структурой данных стека. Вместо этого требуется полное дерево.

Рассмотрим следующий код, который действительно компилируется в gcc, как предлагает KennyTM.

#include <stdio.h> typedef double (*retdouble)(); retdouble wrapper(double a) { double square() { return a * a; } return square; } int use_stack_frame(double b) { return (int)b; } int main(int argc, char** argv) { retdouble square = wrapper(3); printf(«expect 9 actual %fn», square()); printf(«expect 3 actual %dn», use_stack_frame(3)); printf(«expect 16 actual %fn», wrapper(4)()); printf(«expect 9 actual %fn», square()); return 0; }

Я разместил то, что большинство людей ожидало бы напечатать, но на самом деле это печатается:

expect 9 actual 9.000000 expect 3 actual 3 expect 16 actual 16.000000 expect 9 actual 16.000000

Обратите внимание, что последняя строка вызывает функцию “квадрат”, но значение “a”, которое она обращается, было изменено во время вызова оболочки (4). Это связано с тем, что отдельный кадр стека не создается для каждого вызова “обертки”.

Обратите внимание: эти типы вложенных функций на самом деле довольно распространены в других языках, которые поддерживают их как lisp и python (и даже последние версии Matlab). Они приводят к некоторым очень мощным функциям функционального программирования, но они исключают использование стека для хранения локальных фреймов области.

Ответ №8void foo() { class local_to_foo { public: static void another_foo() { printf(«whatevs»); } }; local_to_foo::another_foo(); }

Или lambda в С++ 0x.

Ответ №9

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

#include <iostream> int f() { class G { public: int operator()() { return 1; } } g; return g(); } int main() { std::cout << f() << std::endl; }

Имейте в виду, что вы не можете передать функцию, определенную в локальном классе, алгоритму STL, например sort().

int f() { class G { public: bool operator()(int i, int j) { return false; } } g; std::vector<int> v; std::sort(v.begin(), v.end(), g); // Fails to compile }

Ошибка, которую вы получите от gcc, – “test.cpp: 18: ошибка: нет соответствующей функции для вызова сортировки (__ gnu_cxx:: __ normal_iterator → , __gnu_cxx:: __ normal_iterator → , f():: G &)”

Ответ №10

Невозможно объявить функцию внутри функции. Однако вы можете объявить функцию внутри пространства имен или внутри класса на С++.

Ответ №11

Не в стандарте C, а gcc и clang поддерживают их как расширение. См. руководство пользователя gcc.

Ответ №12

Хотя C и С++ запрещают вложенные функции, несколько компиляторов поддерживают их в любом случае (например, если память служит, gcc может, по крайней мере, с правильными флагами). Однако вложенный функтор гораздо более портативен.

Ответ №13

К сожалению, нет вложенных функций в C/С++.

Ответ №14

Как упоминалось в других ответах, стандартные C и С++ не позволяют вам определять вложенные функции. (Некоторые компиляторы могут разрешить это как расширение, но я не могу сказать, что видел, как он использовался).

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

#include <stdlib.h> #include <stdio.h> int main( int argc, char* argv[]) { int foo(int x); /* int bar(int x) { // this can’t be done return x; } */ int a = 3; printf( «%dn», foo(a)); return 0; } int foo( int x) { return x+1; }

Объявление функции без явного “спецификатора привязки” имеет ссылку extern. Таким образом, пока объявление имени foo в функции main() ограничено значением main(), оно будет ссылаться на функцию foo(), которая определена позже в файле (или в другом файле, если там, где foo() определяется).

Оцените статью
Добавить комментарий