Как std::function знает о соглашении о вызовах?
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;
}
Я был обеспокоен тем, как назначить __stdcall function
в std::function
объект. Но без какого-либо указания соглашения о вызовах, похоже, работает нормально. Как может std::function
знаете, что такое соглашение о вызовах?
1 ответ
std::function
может хранить указатели на функции, которые используют любое соглашение о вызовах.
§ 20.8.11.2:
Шаблон класса функции предоставляет полиморфные оболочки, которые обобщают понятие указателя на функцию. Оболочки могут хранить, копировать и вызывать произвольные вызываемые объекты (20.8.1), используя сигнатуру вызова (20.8.1), что позволяет функциям быть объектами первого класса.
Как добавил John Calsbeek: в стандарте нет ничего особенного в отношении соглашений о вызовах, но компиляторы выполняют свою работу, а указатели на функции содержат информацию о соглашении.
С указателями на функции вам нужно будет указать необычное соглашение о вызовах:
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;