Не так давно вимоги-вирази (словосполучення, введене другим вимагає) не були дозволені в обмеженнях-виразах (словосполучення, введене першим, вимагає). Це могло з'явитися лише у поняттях визначення. Насправді це саме те, що пропонується в розділі цього документу, де ця заява з’являється.
Однак у 2016 році була пропозиція зняти це обмеження [Примітка редактора: P0266 ]. Зауважте підкреслення пункту 4 розділу 4 цього документа. І таким чином народився вимагає вимагає.
По правді кажучи, я ніколи фактично не застосовував це обмеження в GCC, тому це завжди було можливо. Я думаю, що Уолтер, можливо, це виявив і вважав корисним, що веде до цієї роботи.
Щоб хтось не думав, що я не чутливий до письма вимагає двічі, я витратив деякий час, намагаючись визначити, чи можна це спростити. Коротка відповідь: ні.
Проблема полягає в тому, що є два граматичні конструкції, які потрібно ввести після списку параметрів шаблону: дуже часто вираз обмеження (як P && Q
) та періодично синтаксичні вимоги (подібні requires (T a) { ... }
). Це називається вимогою-виразом.
Перший вимагає введення обмеження. Друга вимагає введення вираз-вимагає. Саме так складається граматика. Я взагалі не вважаю це заплутаним.
Я намагався, в один момент, звести їх до єдиної потреби. На жаль, це призводить до деяких серйозно складних проблем розбору. Ви не можете легко сказати, наприклад, якщо a(
після вимоги позначає вкладений піддекспресія або список параметрів. Я не вірю, що ці синтаксиси є ідеальними (див. Обґрунтування рівномірного синтаксису ініціалізації; ця проблема теж є).
Отже, ви робите вибір: make вимагає ввести вираз (як це робиться зараз) або змусити його ввести параметризований список вимог.
Я вибрав поточний підхід, тому що більшу частину часу (як майже у 100% часу) я хочу чогось іншого, ніж вимагати висловлення. І в надзвичайно рідкісному випадку я захотів висловити вимоги для спеціальних обмежень, я дійсно не проти написати слово два рази. Це очевидний показник того, що я не розробив достатньо звукової абстракції для шаблону. (Тому що, якби я мав, це мала б назву.)
Я міг би обрати вимоги, щоб запровадити вираз-вираз. Це насправді гірше, адже практично всі ваші обмеження почали виглядати так:
template<typename T>
requires { requires Eq<T>; }
void f(T a, T b);
Тут друга вимога називається вкладеною вимогою; він оцінює своє вираження (інший код у блоці вимагає виразу не оцінюється). Я думаю, це набагато гірше, ніж статус-кво. Тепер вам потрібно писати двічі скрізь.
Я також міг би використовувати більше ключових слів. Це сама по собі проблема --- і це не лише прокладка велосипедів. Можливо, є спосіб "перерозподілити" ключові слова, щоб уникнути дублювання, але я не задумувався над такою серйозною думкою. Але це насправді не змінює суті проблеми.
noexcept(noexcept(...))
.