[cfe-dev] Clang: Erroneous behavior on windows

Aaron Ballman aaron at aaronballman.com
Mon Mar 23 06:16:14 PDT 2015


On Mon, Mar 23, 2015 at 5:44 AM, Sebastian Redl
<sebastian.redl at getdesigned.at> wrote:
> 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.

With MSVC compatibility turned on, we should be generating an
operator() for every calling convention for non-capturing lambdas.

http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2015/02/20/10594680.aspx

~Aaron



More information about the cfe-dev mailing list