Pytanie Czy będę w stanie zadeklarować constexpr lambda w parametrze szablonu?


Wiem, że to jak otwieranie pudełka Pandora, ale nie przeszkadza mi to. Rozważ prosty przykład:

#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, że lambdy nie mogą być zadeklarowane w kontekście nieocenionym, ale oczywiście tak nie jest. Co jest jeszcze dziwniejszym clangiem 5.0.0 (co, jak sądzę, najpierw częściowo obsługuje constexpr lambda) to kompiluje.

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


18
2018-06-11 15:36


pochodzenie




Odpowiedzi:


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

[expr.prim.lambda] / 2:

Wyrażenie lambda jest prvalue, którego obiekt wynikowy jest nazywany obiekt zamknięcia. Wyrażenie lambda nie pojawia się w nienazwanym operandzie, 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 zaznaczonej jako pogrubioną, wyrażenie lambda nie może pojawić się na liście argumentów szablonu.

Zostało to również wyjaśnione w następnej notatce:

[Uwaga: zamiarem jest zapobieganie pojawianiu się lambdasów w podpisie. - nota końcowa]

Gdybym miał zgadywać, powiedziałbym, że błąd pojawia się, ponieważ począwszy od C ++ 17, lambdy są niejawnie constexpr, co czyni je ważnymi do wywołania w wyrażeniach czasu kompilacji, takich jak argumenty szablonów. Ale zdefiniowanie lambda w argumencie szablonu nadal jest nielegalne.


Zauważ, że to ograniczenie zostało zniesione w C ++ 20. :)


24
2018-06-11 15:44



@DanielJour Nie, przepraszam. Ale to spowodowałoby nawet programowanie meta jeszcze mylące :) - Rakete1111
bugs.llvm.org/show_bug.cgi?id=33696 - Trass3r
@ W.F. Jup, akapit, który cytuję, już nie ma :) eel.is/c++draft/expr.prim.lambda#2 - Rakete1111
Miłe znalezisko! Dzięki za udostępnienie! Miejmy nadzieję, że kodery użyją go rozsądnie;) - W.F.
Czekać! Teraz lambda może być zadeklarowana w decltype? : o - W.F.