2017-06-11 14 views
18

Wiem, że to jak otwieranie pudełka Pandora, ale nie przeszkadza mi to. Rozważmy prosty przykład:Czy będę w stanie zadeklarować constexpr lambda w parametrze szablonu?

#include <type_traits> 

template <auto> 
struct Foo: std::false_type { }; 

template <> 
struct Foo<[](){return 1;}()>:std::true_type { }; 

int main() { 
    static_assert(Foo<1>::value); 
} 

wiem lambda nie może być uznana wewnątrz unevaluated kontekście, ale oczywiście to nie jest w tym przypadku. Co jest jeszcze dziwniejszym clangiem 5.0.0 (co, jak sądzę, najpierw częściowo obsługuje constexpr lambda) does compile it.

Czy jest to błąd kompilatora, czy też C++ 17 na to pozwala?

Odpowiedz

24

Nie, to błąd kompilatora. gcc 7.1 poprawnie odrzuca kod.

[expr.prim.lambda]/2:

lambda ekspresja jest prvalue którego celem wynik jest nazywany przedmiot zamykający. Wyrażenie lambda nie pojawia się w niezaawansowanym argumencie, w szablonowym argumencie, w deklaracji aliasowej, w deklaracji typedef lub w deklaracji szablonu funkcji lub funkcji poza jego treścią funkcji i domyślnymi argumentami.

Jak widać z części, którą zaznaczono jako pogrubioną, wyrażenie lambda nie może pojawić się na liście argumentów szablonu.

Jest również jasne, w kolejnej nocie:

[Uwaga: Chodzi o to, aby zapobiec pojawianiu lambdy w podpisie. - koniec uwaga]

Gdybym miał zgadywać, powiedziałbym, że chodzi o błąd, ponieważ zaczynając od C++ 17, lambdas są domyślnie constexpr, co sprawia, że ​​ważne, aby być wywołana w czasie kompilacji wyrażeń, jak argumenty szablonu. Ale zdefiniowanie lambda w argumencie szablonu nadal jest nielegalne.


Należy zauważyć, że to ograniczenie zostało zniesione w C++ 20. :)

+0

Tak, myślałem, że standardowym zamiarem komisji było zaprezentowanie tego, dlatego zdziwiłem się, że Clang zrobił kompilator kodu. Poczekam trochę, a następnie zaakceptuję twoją odpowiedź. Dzięki! –

+0

Każdy pomysł na: * dlaczego * zostało to nielegalne? Wydaje się bardzo przydatne, dzięki czemu programowanie meta łatwiejsze ... –

+3

@ DanielJour Nie, przepraszam. Ale to spowodowałoby, że programowanie meta nawet * bardziej * mylące :) – Rakete1111

Powiązane problemy