#c #c 20
Вопрос:
как определить тип-это лямбда ? нравится std::is_function
? Я тоже пробовал std::is_invocable
, но для этого нужны именно типы параметров.
Комментарии:
1. Это просто признак того, что вам нужно переосмыслить более широкую проблему, которую вы пытаетесь решить, и найти другой способ, который не зависит от знания того, является ли тип лямбда.
2. Лямбды не являются особыми в C . Никогда не было причин писать функцию, которая может принимать только лямбду. Функции должны принимать любой конкретный вызываемый объект, соответствующий его использованию.
3. @BrianBi: да, по моему разумению лямбда является синтаксическим сахаром для стандартного класса функтора, который пользователь может писать от руки (надписи на ней не конструктор, аргументы, доводы, основания
operator()
); в лучшем случае, с библиотеку RTTI, вы могли бы сделать страшную эвристики, чтобы выяснить, если базовое имя-кот плюнул вверх (вероятно, компилятор генерируется имя лямбда) и неопределенно человека название (хотя имя-коверкая составители применить это будет выглядеть как кошка больна тоже). Но даже если вы можете, и даже если эвристика работает, для этого никогда не будет причин.4. @VeNToR: Я сильно подозреваю, что это проблема XY . Как вы думаете, почему вам нужно это делать? Какую проблему вы решаете?
5. @VeNToR: Я не прошу у вас весь ваш код. Просто объяснение того, почему вы считаете важным специально идентифицировать лямбды и обрабатывать их иначе, чем другие функторы, для которых они являются эквивалентами. Объяснение может привести к ответу, который решит вашу реальную проблему; весь смысл проблем XY в том, что вы остановились на плохом решении вашей реальной проблемы, и вы пытаетесь заставить плохое решение работать, пренебрегая описанием реальной проблемы, у которой есть хорошее решение.
Ответ №1:
Вы не можете проверять все вызываемые типы, не имея точных параметров. Возьмем, к примеру, это:
auto my_lambda = [](std::integral auto number) {};
Существует несколько свойств, которые затрудняют проверку без знания типов параметров:
- Вы не можете взять адрес
operator()
, так как это шаблон. Вы могли бы взять адресoperator()<int>
, но вам нужно было бы заранее знать тип - Вы не можете попробовать лямбду с типом «преобразовать во что угодно», так как она не является интегралом
- Нет никаких других наблюдаемых свойств такого типа, которые можно было бы наблюдать.
Из-за этого действительно трудно иметь is_lambda
какую-то черту характера. Кроме того, у вас может быть что-то подобное:
struct A {
void operator()(int) const {}
};
Это было бы неотличимо от лямбды.
Однако существуют очень хитрые способы проверить, является ли тип лямбдой или нет.
Я бы настоятельно рекомендовал этого не делать.
Теоретически вы могли бы проверить имя типа с помощью __PRETTY_FUNCTION
или __FUNCSIG__
и проверить , похоже ли имя на имя, сгенерированное компилятором для лямбды, но это исключило бы любые другие определяемые пользователем вызываемые типы, которые являются и должны приниматься как лямбда.
Я оставляю реализацию в качестве упражнения для читателя.