10
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呼び出し規約が何であるかをどうやって知ることができますか?

4

1 に答える 1

8

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;
于 2012-04-16T07:33:42.690 に答える