Как определить, является ли тип лямбда?

#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__ и проверить , похоже ли имя на имя, сгенерированное компилятором для лямбды, но это исключило бы любые другие определяемые пользователем вызываемые типы, которые являются и должны приниматься как лямбда.

Я оставляю реализацию в качестве упражнения для читателя.