Я пытаюсь понять различные способы указания предложения С++. Мне нужно более глубокое понимание, а не техническое решение для определения ограничения.
Подумайте о функции шаблона:
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;
даже в примерах, где лямбда не вызывается, они, похоже, хотят, чтобы лямбда вызывалась автоматически, но ¯\_(ツ)_/¯
Ух. Это не единственное требование, поскольку это первичное выражение, оно должно быть логической константой времени компиляции.