Guillaume Racicot
Guillaume Racicot

Reputation: 41780

Is the call operator of lambdas required to have linkage?

I have some code that deal with address of functions, lambdas and template arguments.

Here's a snippet that shows to me some usage of these address to functions:

#include <type_traits>

int main() {
    auto l = []{};
    using L = decltype(l);

    // fine, am I just lucky?
    using type1 = std::integral_constant<decltype(&L::operator()), &L::operator()>;

    struct Bar {
        static void baz() {}
    };

    // error!
    using type2 = std::integral_constant<decltype(&Bar::baz), &Bar::baz>;
}

The thing is, for being able to send &Bar::baz as template argument, it must have linkage, hence the error.

Why the lambda case works? Is it because it is not static or because the call operator of the lambda has linkage?

Upvotes: 3

Views: 266

Answers (1)

T.C.
T.C.

Reputation: 137325

The closure type of a lambda is an unnamed class, see [expr.prim.lambda.closure]/1. A member function of a class has the same linkage, if any, as the name of its containing class; see [basic.link]/5. If the containing class has no name (not even for linkage purposes), then its member functions have no linkage.

Additionally, the closure type of a local lambda is a local class, and local classes, even those with a name, have no linkage; see [expr.prim.lambda.closure]/2 and [basic.link]/8.

Before C++17, the linkage requirement, found in [temp.arg.nontype]/1.3, applies to pointers and references, but not pointers to member. Under these rules, GCC is correct in accepting your lambda case and rejecting your Bar::baz case.

N4268 removed the linkage requirement entirely for C++17 while revamping the rules for template non-type arguments. In C++17, both examples should be accepted.

Upvotes: 3

Related Questions