1

No idea how I could rephrase the title better.

I want to move low level code outside of a simple function and move the code inside the class so the class takes care of the more complicated stuff.
I want to go from this:

void a(void) {
    [low level operation];
    //User typed simple operations
    [low level operation];
}

static void AClass::b() {
    register(a); //register(void (__cdecl *func)())
}

int main(void) {
    AClass::b();
    return 0;
}

To:

void a(void) {
    //[no low level operation]
    //User typed simple operations
    //[no low level operation]
}

static void AClass::b(void (*func)()) {
    auto funcA = [] (void (*func)()) -> void (*)() { 
        [that first low level operation]; 
        func(); //Which is: void a(void);
        [the second low level operation]; 
    };
    register(funcA(func));
}

int main(void) {
    AClass::b(&a);
    return 0;
}

At the moment I get the error "< lambda >::operator ()' : function must return a value" - because of the pointer. How could I solve this problem? Returning just void doesn't work. Passing the arguments(the function "func") by reference to the lambda also doesn't work(Cause in this case the lambda is not just a function any more but a Class) - the register(void (__cdecl *func)()) can't convert the now not a function lambda.

Any ideas how to solve my problem?

4

2 回答 2

1

有状态的 lambda 不能转换为函数指针。

只有没有状态的 lambda 可以转换为函数指针。

您的州需要通过一些后门滑入。glutDisplayFunc,只需要一个无状态函数指针。修改它是不可能的。

如果你能找到一个后门来存储一些东西,你可以用它来存储一个任意的 lambda。在这种情况下,glutDisplayFunc与当前窗口相关联。有没有什么地方可以在当前窗口中推动状态,并找出是哪一个?

假设你找到这样一个void*. 然后只需分配 a std::function<void()>,将其推入其中,并注册以下 lambda:

void AClass::b(void (*func)()) {
   auto funcA = [func] () { 
     [that first low level operation]; 
     func(); //Which is: void a(void);
     [the second low level operation]; 
   };
   registerPVoidSomewhere( new std::function<void()>( funcA ) );

   register([]() {
     void* pVoid = getPVoidFromWhereIHideItAbove();
     std::function<void()>* pFunc = reinterpret_cast<std::function<void()>*>( pVoid );
     if (pFunc) {
       (*pFunc)();
     };
   } );
}

现在,我敢打赌,当调用 时,当您可以询问当前窗口是什么glutDisplayFunc时,它会从上下文中调用。glut也许那个窗口有一个用户定义的位置void*,或者你可以有一个从窗口指针到void*你管理的全局映射(在第二种情况下,你甚至可以有一个从窗口指针到的全局映射std::function<void()>,并摆脱那个讨厌的铸件)。

于 2013-03-29T01:49:17.610 回答
0

There are two problems, one with the types and one that you declare the lambda to return a function pointer but actually don't return anything.

The first can easily be solved by using templates:

struct AClass
{
    template<typename Ft>
    static void b(Ft func)
    {
        auto funcA = [&func]()
        {
            // Do some stuff
            func();
            // Do some other stuff
        };
        some_register_function(funcA);
    }
};

As you can see I also changed the lambda declaration, because in your version you actually call it, which will also call the function pointer you pass in as argument, and this solves the second problem.

Please note that I don't actually know if it will work, as glutDisplayFunc is a pure C function in a pure C library, and don't know anything about lambdas or function objects.

于 2013-03-29T01:26:13.247 回答