[cfe-dev] Clang: Erroneous behavior on windows

Sebastian Redl sebastian.redl at getdesigned.at
Mon Mar 23 02:44:13 PDT 2015


On 3/22/2015 6:25 PM, Daniel Berenyi wrote:
> Dear All,
>
> //-----------------------------------------------
> template<typename F>
>   decltype(auto) deduce(F f){ return &decltype(f)::operator(); }
>
> template<typename C, typename R, typename A> decltype(auto)
>   signaturehelper( R(C::*f)(A)const ) { return R(); }
>
> int main()
> {
>   auto l = [](int x){return x*2;};
>   decltype(signaturehelper(deduce(l))) p;
> }
> //--------------------------------
>
> It fails with:
> decltype(signaturehelper(deduce(l))) p;
>                ^~~~~~~~~~~~~~~
> note: candidate template ignored: substitution failure [with C = 
> (lambda at main.cpp:9:11), R = float, A = int]
> decltype(auto) signaturehelper(R(C::*f)(A)const) { return R(); }
>
I've had exactly the same problem when I tried to find the argument type 
of a lambda. Here's how I worked around it:

         template <typename R, typename C, typename Arg, typename... Args>
         struct FirstArgumentImpl<R (C::*)(Arg, Args...) const>
         {
             using type = Arg;
         };
         // for Clang on Windows
         template <typename R, typename C, typename Arg, typename... Args>
         struct FirstArgumentImpl<R (__cdecl C::*)(Arg, Args...) const>
         {
             using type = Arg;
         };

The issue appears to be that Clang gives the lambda's operator() a 
__cdecl calling convention instead of the default member __thiscall 
calling convention.

Sebastian



More information about the cfe-dev mailing list