https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104358

--- Comment #2 from qingzhe huang <nickhuang99 at hotmail dot com> ---
Here are more tests (https://www.godbolt.org/z/5qc8jTGa8) to show that only
msvc is giving the correct result. 

It just illustrates the use cases of this definition and why it should be
allowed.

1. By using operator "+", here the type "Lambda" is just a free function
pointer.

template<typename T>
using Lambda=decltype(+[](T){});
static_assert(is_same_v<Lambda<int>, void(*)(int)>); 

2. The "foo" takes "Lambda" as parameter
template<typename T>
T foo(T&&, Lambda<T>); 

3. As "Lambda<T>" is just a function pointer, "foo" should allow both free
function pointer or lambda(by conversion operator) to be used as argument. And
because GCC mistakenly consider "foo<int>" signature as "int(*)(int&&,
/*Lambda<int>*/int)", this is not possible.

static_assert(is_same_v<decltype(&foo<int>), int(*)(int&&, int)>); 

These are use cases for "foo":
a) using lambda directly
    foo<int>(5, [](int n){});// lambda conversion operator!
b) using converted function pointer from lambda by operator "+"
    auto funptr=+[](int n){};
    foo<int>(5, funptr);
c) directly using a function pointer
    void(*ptr)(int)=funptr;
    foo<int>(5, ptr);

Reply via email to