Nie tak dawno temu wyrażenia wymagań (fraza wprowadzona przez drugie wymagania) nie były dozwolone w wyrażeniach ograniczających (fraza wprowadzona przez pierwsze wymagania). Mogło pojawić się tylko w definicjach pojęć. W rzeczywistości jest to dokładnie to, co zaproponowano w części tego dokumentu, w której pojawia się to twierdzenie.
Jednak w 2016 r. Pojawiła się propozycja złagodzenia tego ograniczenia [przyp. Red . : P0266 ]. Zwróć uwagę na przekreślenie akapitu 4 w sekcji 4 pracy. I tak narodził się wymaga wymagań.
Prawdę mówiąc, nigdy nie wdrożyłem tego ograniczenia w GCC, więc zawsze było to możliwe. Myślę, że Walter mógł to odkryć i uznał to za przydatne, co doprowadziło do tego artykułu.
Żeby ktoś nie pomyślał, że nie jestem wrażliwy na pisanie, wymaga dwóch rzeczy, spędziłem trochę czasu próbując ustalić, czy można to uprościć. Krótka odpowiedź: nie.
Problem polega na tym, że istnieją dwie konstrukcje gramatyczne, które należy wprowadzić po liście parametrów szablonu: bardzo często wyrażenie ograniczające (jak P && Q
) i czasami wymagania składniowe (podobne requires (T a) { ... }
). Nazywa się to wyrażeniem wymagania.
Pierwszy wymóg wprowadza ograniczenie. Drugi wymaga wprowadza wyrażenie wymagań. Tak po prostu komponuje się gramatyka. Nie wydaje mi się to wcale mylące.
W pewnym momencie próbowałem złożyć je na pojedyncze wymagania. Niestety prowadzi to do poważnych problemów z analizowaniem. Nie można łatwo stwierdzić, na przykład, czy (
po wymaganiu oznacza zagnieżdżone wyrażenie podrzędne lub listę parametrów. Nie wierzę, że istnieje idealne ujednoznacznienie tych składni (patrz uzasadnienie jednolitej składni inicjalizacji; ten problem też tam jest).
Dokonujesz więc wyboru: make wymaga wprowadzenia wyrażenia (tak jak teraz) lub sprawi, że wprowadzi sparametryzowaną listę wymagań.
Wybrałem obecne podejście, ponieważ przez większość czasu (prawie w 100%) chcę czegoś innego niż wyrażenie wymagania. A w niezwykle rzadkim przypadku, gdy chciałem wyrażenia wymagań dla ograniczeń ad hoc, naprawdę nie mam nic przeciwko dwukrotnemu napisaniu tego słowa. To oczywista wskazówka, że nie opracowałem wystarczająco solidnej abstrakcji dla szablonu. (Bo gdybym miał, miałoby imię.)
Mogłem zdecydować, aby wymagania wprowadziły wyrażenie wymagań. W rzeczywistości jest to gorsze, ponieważ praktycznie wszystkie twoje ograniczenia zaczęłyby wyglądać tak:
template<typename T>
requires { requires Eq<T>; }
void f(T a, T b);
Tutaj drugie wymaganie nazywa się wymaganiem zagnieżdżonym; oblicza swoje wyrażenie (inny kod w bloku wyrażenia wymagania nie jest oceniany). Myślę, że jest to o wiele gorsze niż status quo. Teraz możesz pisać wymaga dwukrotnie wszędzie.
Mogłem też użyć więcej słów kluczowych. Jest to problem sam w sobie - i nie chodzi tylko o porzucanie roweru. Może istnieć sposób na „redystrybucję” słów kluczowych, aby uniknąć powielania, ale nie zastanawiałem się nad tym poważnie. Ale to nie zmienia istoty problemu.
noexcept(noexcept(...))
.