Я пытаюсь понять различные способы указания предложения С++. Мне нужно более глубокое понимание, а не техническое решение для определения ограничения.
Подумайте о функции шаблона:
template<typename T>
T func(T t) {
return t;
}
Можно добавить простое, но бесполезное предложение require:
template<typename T>
requires true
T func(T t) {
return t;
}
и я мог бы вызвать эту функцию так:
foo(1);
template<typename T>
requires [] { return true; }
T func(T t) {
return t;
}
Используя cl.exe из VS2019/VS2022, я получаю ошибку компиляции, похожую на (переведено):
ошибка C7607: атомарное ограничение должно быть постоянным выражением типа Bool...
Я пробовал использовать constexpr, но безуспешно.
Чего я не хочу: requires ([] { return true; }())
@HolyBlackCat: Я понимаю это и думал, что смогу сделать лямбда-выражение constexpr, но мне это не удалось. Вот почему я задал этот вопрос - я действительно застрял.
Лямбда-выражение не является bool, пока вы его не вызовете. Кажется, вы это знаете (последний абзац вашего вопроса), поэтому я не понимаю, почему вы думали, что вам сойдет с рук не вызвать.
вы даете ссылку, но непонятно, что именно здесь en.cppreference.com/w/cpp/language/constraints#Requires_clauses заставило вас сделать вывод, что ваш фрагмент подойдет





Тип лямбда-выражения — это тип класса, определенный компилятором. Не имеет значения, что возвращает лямбда, если вы на самом деле не вызываете лямбду.
Типы классов не являются логическими типами. Поскольку стандарт требует, чтобы выражение в предложении requires было постоянным выражением логического типа. Вы можете сделать лямбда-выражение постоянным выражением, но не можете сделать его логическим.
Я неверно истолковал описание на XXX, и ваш ответ мне помог, особенно потому, что вы ссылались на стандарт C++. Большое спасибо! Также спасибо всем остальным комментаторам, я понял, что не могу сформулировать свой вопрос по существу и что это, должно быть, сбивает с толку. Простите за это.
Как я могу использовать лямбда-выражение в качестве постоянного основного выражения в предложении require?
Немедленным вызовом лямбды.
Это связано с тем, что [] { return true; } является объектом некоторого типа, специфичного для компилятора (так называемого типа замыкания), но выражение require должно быть постоянным выражением типа bool.
Итак, чтобы это заработало, просто вызовите лямбду, используя оператор вызова функции () с дополнительными круглыми скобками вокруг него. Демо
Кажется, они уже знают (отчасти?) это, как показано в последнем абзаце вопроса.
@HolyBlackCat Другой ответ также указывает на то же самое. ОП, похоже, не знает, что лямбда не конвертируется в bool. Они? Какой последний абзац вы имеете в виду? Я пытался найти этот абзац, но не вижу нигде, где бы упоминалось что-нибудь о преобразовании bool и т. д. Они знают только, что ограничение должно быть типа bool.
Я имел в виду «Чего я не хочу: requires ([] { return true; }())». Я не критикую ваш ответ, просто не понимаю, чего хочет ОП. Поскольку они return true; даже в примерах, где лямбда не вызывается, они, похоже, хотят, чтобы лямбда вызывалась автоматически, но ¯\_(ツ)_/¯
Ух. Это не единственное требование, поскольку это первичное выражение, оно должно быть логической константой времени компиляции.