is it possible in C or C++ to create a function inside another?

后端 未结 15 1930
迷失自我
迷失自我 2020-12-15 09:18

Could someone please tell me if this is possible in C or C++?

void fun_a();
//int fun_b();
...
main(){
   ...
   fun_a();
   ...
   int fun_b(){
     ...
            


        
相关标签:
15条回答
  • 2020-12-15 09:51

    No, and there's at least one reason why it would complicate matters to allow it. Nested functions are typically expected to have access to the enclosing scope. This makes it so the "stack" can no longer be represented with a stack data structure. Instead a full tree is needed.

    Consider the following code that does actually compile in gcc as KennyTM suggests.

    #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 %f\n", square());
      printf("expect  3 actual %d\n", use_stack_frame(3));
      printf("expect 16 actual %f\n", wrapper(4)());
      printf("expect  9 actual %f\n", square());
      return 0;
    }
    

    I've placed what most people would expect to be printed, but in fact, this gets printed:

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

    Notice that the last line calls the "square" function, but the "a" value it accesses was modified during the wrapper(4) call. This is because a separate "stack" frame is not created for every invocation of "wrapper".

    Note that these kinds of nested functions are actually quite common in other languages that support them like lisp and python (and even recent versions of Matlab). They lead to some very powerful functional programming capabilities, but they preclude the use of a stack for holding local scope frames.

    0 讨论(0)
  • 2020-12-15 09:52

    No but in C++0x you can http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions which may take another few years to fully support. The standard is not complete at the time of this writing.

    -edit-

    Yes

    If you can use MSVC 2010. I ran the code below with success

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

    output

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

    (I wrote >> c:\dev\loc\uniqueName.txt in the project working arguments section and copy pasted this result)

    0 讨论(0)
  • 2020-12-15 09:54

    You can nest a local class within a function, in which case the class will only be accessible to that function. You could then write your nested function as a member of the local class:

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

    Keep in mind, though, that you can't pass a function defined in a local class to an STL algorithm, such as 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
    }
    

    The error that you would get from gcc is "test.cpp:18: error: no matching function for call to `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, f()::G&)' "

    0 讨论(0)
提交回复
热议问题