What's the default calling convention of a C++ lambda function?

后端 未结 2 1215
自闭症患者
自闭症患者 2021-02-19 02:43

The following code was compiled with VC++ 2012:

void f1(void (__stdcall *)())
{}

void f2(void (__cdecl *)())
{}

void __cdecl h1()
{}

void __stdcall h2()
{}

i         


        
2条回答
  •  时光说笑
    2021-02-19 03:30

    A stateless lambda function is still a class, but a class that can be implicitly converted into a function pointer.

    The C++ standard doesn't cover calling conventions, but there is little reason why a stateless lambda could not create a wrapper in any calling convention that forwards through to the stateless lambda when the lambda is converted to a function pointer.

    As an example, we could do this:

    #include 
    
    void __cdecl h1() {}
    void __stdcall h2(){}
    
    // I'm lazy: 
    typedef decltype(&h1) cdecl_nullary_ptr;
    typedef decltype(&h2) stdcall_nullary_ptr;
    
    template
    struct make_cdecl {
      static void __cdecl do_it() {
        StatelessNullaryFunctor()();
      }
    };
    template
    struct make_stdcall {
      static void __stdcall do_it() {
        StatelessNullaryFunctor()();
      }
    };
    
    struct test {
      void operator()() const { hidden_implementation(); }
    
      operator cdecl_nullary_ptr() const {
        return &make_cdecl::do_it;
      }
      operator stdcall_nullary_ptr() const {
        return &make_stdcall::do_it;
      }
    };
    

    where our test stateless nullary class can be converted into both a cdecl and stdcall function pointer implicitly.

    The important part of this is that the calling convention is part of the type of the function pointer, so operator function_type knows what calling convention is being requested. And with perfect forwarding, the above can even be efficient.

提交回复
热议问题