Home > Enterprise >  Get a pointer to a templated lambda operator () without captures
Get a pointer to a templated lambda operator () without captures

Time:10-06

Can anyone tell me a valid way to get a pointer to a templated lamda (without caputes) operator () ? Already tried two alternatives:

int main()
{
    static
    auto l = []<bool a, bool b>( unsigned c ) -> unsigned
    {
        return (unsigned)a   b   c;
    };
    using fn_t = unsigned (*)( unsigned );
    fn_t fnA = &l.operator ()<true, false>; // doesn't work
    fn_t fnB = &decltype(l)::operator ()<true, false>; // also doesn't work
}

clang(-cl) 12:

x.cpp(9,13): error: cannot create a non-constant pointer to member function
        fn_t fnA = &l.operator ()<true, false> ; // doesn't work
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
x.cpp(10,14): error: address of overloaded function 'operator()' does not match required type
      'unsigned int (unsigned int)'
        fn_t fnB = &decltype(l)::operator ()<true, false> ; // also doesn't work
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.cpp(4,11): note: candidate function template has different qualifiers (expected unqualified but found 'const')
        auto l = []<bool a, bool b>(unsigned c) -> unsigned
                 ^

MSVC 2019 latest update:

x.cpp(9): error C2276: '&': illegal operation on bound member function expression
x.cpp(10): error C2440: 'initializing': cannot convert from 'overloaded-function' to 'fn_t'
x.cpp(10): note: None of the functions with this name in scope match the target type

CodePudding user response:

The type of the address of lambda's operator() is a member function pointer, however, the definition of your fn_t is just a free function pointer. You should define your fn_t as:

using fn_t = unsigned int (decltype(l)::*)(unsigned int) const;

Then the following should work:

fn_t fnA = &decltype(l)::operator ()<true, false>;

Or, why not?

auto fnB = &decltype(l)::operator ()<true, false>;

Demo.

CodePudding user response:

It is the lambda which can be converted to function pointer in some conditions (which are not there here), not its member operator(). And you cannot convert member pointer to function pointer.

One workaround is to use another lambda.

fn_t fn = [](unsigned c) { return decltype(l){}.operator()<true, false>(c); };

Demo

  • Related