代码之家  ›  专栏  ›  技术社区  ›  Daniel Trebbien

C++0x是否支持SytStDeLead或EXCENT“C”捕获LAMBDAS?

  •  15
  • Daniel Trebbien  · 技术社区  · 16 年前

    昨天我在想,是否可以使用C++0x LAMBDA函数的便利性来编写Windows API函数的回调。

    例如,如果我想使用lambda作为 EnumChildProc 具有 EnumChildWindows ?类似:

    EnumChildWindows(hTrayWnd, CALLBACK [](HWND hWnd, LPARAM lParam) {
            // ...
            return static_cast<BOOL>(TRUE); // continue enumerating
        }, reinterpret_cast<LPARAM>(&myData));
    

    另一种用法是写 extern "C" C例程的回调。例如。:

    my_class *pRes = static_cast<my_class*>(bsearch(&key, myClassObjectsArr, myClassObjectsArr_size, sizeof(my_class), extern "C" [](const void *pV1, const void *pV2) {
            const my_class& o1 = *static_cast<const my_class*>(pV1);
            const my_class& o2 = *static_cast<const my_class*>(pV2);
    
            int res;
            // ...
            return res;
        }));
    

    这可能吗?

    我可以理解,捕捉变量的lambda永远不会与c兼容,但至少在我看来是可能的。 一无所获 lambda可以兼容。

    3 回复  |  直到 10 年前
        1
  •  14
  •   Johannes Schaub - litb    16 年前

    没有捕获的羔羊 are implicitly convertible 指向指向函数的指针(由闭包类型定义的非显式转换函数)。

    FCD似乎没有指定函数指针类型的函数类型的语言链接,因此如果需要将此函数指针传递给C函数,则C++函数和C函数的调用约定需要相同。我相信在窗户上是这样的。因此,您应该能够将lambda传递给Windows API函数

    typedef void(*callbackType)(void *userData);
    extern "C" void someCFunction(callbackType callback);
    
    int main() {
      someCFunction([](void *userData) { /* ... */ });
    }
    

    FCD措辞 5.1.2/6 :

    没有lambda捕获的lambda表达式的闭包类型具有一个公共的非虚拟非显式常量转换函数,该函数指向的指针与闭包类型的函数调用运算符具有相同的参数和返回类型。此转换函数返回的值应为函数的地址,当调用该函数时,它与调用闭包类型的函数调用运算符具有相同的e_etc。

    我认为最终的标准应该有一个注释,即对于C链接函数指针和C++链接函数指针都有转换函数,因为C函数指针的可转换性是这个功能的目标之一。

        2
  •  2
  •   DrPizza    16 年前

    没有什么特别好的理由不应该把这扩展到捕捉羔羊。它需要一些动态代码生成,但是它不应该超出编译器编写者的智慧,而且它将使与旧的C API的互操作变得更容易——不再需要通过非类型化的void*传递参数(并非所有API都提供)。

        3
  •  1
  •   Shafik Yaghmour    10 年前

    函数指针的语言链接从一个捕获的lambda的转换中没有在C++ 11标准中指定,而是在 defect report 1557 上面写着:

    5.1.2[expr.prim.lambda]第6段未规定闭包类型转换函数的函数类型的语言链接。

    解决的办法是语言链接应该是C++。

    没有lambda捕获的lambda表达式的闭包类型有一个公共非虚拟非显式转换函数,用C++语言链接(7.5(dCL,链接))指向函数。与闭包类型的函数调用运算符具有相同的参数和返回类型。返回的值…

    我们可以在C++ 14标准草案中找到这种语言,因为它的地位是 DRWP 这似乎不适用于C++ 11。