C++ std::function如何知道调用约定? int\uu cdecl ccall(int i) { wprintf(L“ccall(%d)”,i); 返回0; } int_uustdcall stdcall(int i) { wprintf(L“stdcall(%d)”,i); 返回0; } 内部cdecl wmain(内部argc,wchar\u t**argv) { std::功能fnc=ccall; std::function fnstd=stdcall; fnc(10);//印刷良好 fnstd(100);//打印良好 返回0; }

C++ std::function如何知道调用约定? int\uu cdecl ccall(int i) { wprintf(L“ccall(%d)”,i); 返回0; } int_uustdcall stdcall(int i) { wprintf(L“stdcall(%d)”,i); 返回0; } 内部cdecl wmain(内部argc,wchar\u t**argv) { std::功能fnc=ccall; std::function fnstd=stdcall; fnc(10);//印刷良好 fnstd(100);//打印良好 返回0; },c++,c++11,calling-convention,C++,C++11,Calling Convention,我关心的是如何将\uu stdcall函数分配给std::function对象。 但是没有任何指定的调用约定,它看起来工作得很好。std::function如何知道调用约定是什么?std::function能够存储使用任何调用约定的函数指针 §20.8.11.2: 函数类模板提供了多态包装,概括了函数指针的概念。包装器可以存储、复制和调用任意可调用对象(20.8.1),给定调用签名(20.8.1),允许函数成为第一类对象 As:标准中没有关于调用约定的特别规定,但是编译器正在执行他们的工作,函数

我关心的是如何将
\uu stdcall函数
分配给
std::function
对象。
但是没有任何指定的调用约定,它看起来工作得很好。
std::function
如何知道调用约定是什么?

std::function
能够存储使用任何调用约定的函数指针

§20.8.11.2:

函数类模板提供了多态包装,概括了函数指针的概念。包装器可以存储、复制和调用任意可调用对象(20.8.1),给定调用签名(20.8.1),允许函数成为第一类对象


As:标准中没有关于调用约定的特别规定,但是编译器正在执行他们的工作,函数指针包含关于约定的信息

对于函数指针,您需要指定异常调用约定:

int __cdecl ccall(int i)
{
    wprintf(L"ccall(%d)", i);
    return 0;
}

int __stdcall stdcall(int i)
{
    wprintf(L"stdcall(%d)", i);
    return 0;
}

int __cdecl wmain(int argc, wchar_t **argv)
{
    std::function<int(int)> fnc = ccall;
    std::function<int(int)> fnstd = stdcall;

    fnc(10); // printed well
    fnstd(100); // printed well
    return 0;
}
typedef int(*c_ptr_t)(int);
typedef int(u stdcall*std_ptr_t)(int);
c_ptr_t c_ptr=ccall;
std_ptr_t std_ptr=stdcall;
//但是std::function并不介意:
标准::功能fnc=c_ptr;
std::功能fnstd=std\u ptr;

同样,编译器知道如何在没有
std::function的情况下调用函数<代码> STD::函数< /代码>使用类型擦除来创建一个内部的小黑箱,当调用“代码> STD::函数< /COD>被要求执行编译器所已经解决的“真实”调用时,我不确定这在技术上是一个答案,因为C++标准几乎不提到调用约定,这里当然没有。答案是
std::function
“记住”使用类型擦除的神奇功能的函数类型,并且大多数合理的编译器中的函数指针包含有关所用调用约定的信息。@JohnCalsbeek:没错,标准中没有比提及引用部分更详细的内容了。调用约定是一个未知的领域,但是编译器表现良好,并且做了需要做的事情。最接近的事情是“C链接”。在那里,编译器只需要让它工作——标准中没有让程序员负责的东西。从广义上讲,由于该标准没有提到调用约定,这种沉默再次使它成为编译器的责任。“函数指针包含关于约定的信息”——具体来说,类型包含该信息,而不是值。我知道,通过ARM/thumb交互工作,函数指针的LSB会切换模式,因此任何一个都可以存储在普通函数指针中。但一般来说,如果一个自由函数有两个(或更多)不同的调用约定,则没有类似的约定。这是因为函数指针值没有指定在这个答案的代码段中需要不同类型的约定。
typedef int(* c_ptr_t)(int);
typedef int(__stdcall * std_ptr_t)(int);

c_ptr_t c_ptr = ccall;
std_ptr_t std_ptr = stdcall;

// But std::function doesn't mind:
std::function<int(int)> fnc = c_ptr;
std::function<int(int)> fnstd = std_ptr;