[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