14

Consider an example:

template <void (*Foo)()>
struct S {
};

int main() {
    struct A {
        static void x() { }
    };
    S<&A::x> s;
}

The code compiles in clang, gcc argue that x doesn't have a linkage... For quite similar example just when using lambda expression:

template <void (*Foo)()>
struct S {
};

int main() {
    auto lambda = []{};
    S<+lambda> s;
}

Both gcc and clang agree not to compile the code: according to gcc the function returned by unary + doesn't have linkage, clang states in contrast that cast operator to the function isn't declared as constexpr. Are there any reasons to disallow lambda cast to function pointer to be used in constexpr context?

Find below errors produced by compilers and the live demos:

gcc:

prog.cc:7:14: error: 'main()::::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::::_FUN()' has no linkage

clang:

prog.cc:7:8: note: non-constexpr function 'operator void (*)()' cannot be used in a constant expression

2
  • 2
    lambda has not linkage because of eel.is/c++draft/basic.link#8 and of course the operator() isn't constexpr, so it's a matter of what error is emitted first - Am I wrong? Commented Dec 16, 2016 at 15:34
  • @skypjack That's the same conclusion I came to, after a bit of searching around (it's the same reason as why A has no linkage). And, in addition to that, types that have no linkage, can't be used as a template argument. Commented Dec 16, 2016 at 15:37

1 Answer 1

10

Clang hasn't implemented constexpr lambdas yet.

GCC is behind in other ways. [temp.arg.nontype]/2's only interesting constraint is that the argument shall be a constant expression. But [expr.const]/(5.2) makes it one, so that's perfectly valid. Perhaps GCC didn't implement N4198 yet, which eliminated the linkage requirement.

Note that both constexpr lambdas and no-linkage function pointer template arguments are post C++14 features.

Sign up to request clarification or add additional context in comments.

3 Comments

No, neither are constexprlambdas part of C++14, nor was N4198 incorporated.
Thanks! I wanted just to be sure :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.