То, что вы хотите, невозможно (или хорошая идея, но не обращайте на это внимания сейчас).
«Функция» по имени в C ++ потенциально представляет множество функций. Он представляет собой перегрузки, создание экземпляров шаблона через вывод аргументов шаблона и т. Д. c. Но чтобы получить функцию указатель , вам необходимо просмотреть все это. Если имя представляет собой набор перегрузки, чтобы получить указатель, вы должны привести это имя к указанной c перегрузке. Если имя представляет шаблон, вы должны предоставить аргументы шаблона для обозначения конкретного c экземпляра.
Это означает, что к тому времени, когда ваша гипотетическая is_callable
концепция будет запущена в тип указателя функции, все разрешение перегрузки и подстановка шаблона уже произошли. Ему дается единственный указатель на конкретный c, четко определенный фрагмент кода, который может быть вызван с подписью, определяемой типом этого указателя.
Ничего из этого не относится к функции объект . Функтор (генерируемый лямбда-выражением C ++ или просто рукописным типом) - это не что иное, как тип с перегрузкой operator()
. И эта перегрузка - это просто имя функции, точно так же, как и любое другое имя: в соответствии с правилами разрешения перегрузки и подстановки шаблонов.
C ++ не позволяет вам задавать вопрос «вот имя; могу ли я вызвать это с помощью что-то ? "
И вообще, это просто бесполезный вопрос.
Используете ли вы эту" вызываемую "концепцию для карри или что-то еще, в какой-то момент какой-то фрагмент кода собирается вызвать некоторую функцию с некоторым набором аргументов, которые в конечном итоге будут каскадно вызывать данную функцию с другим набором аргументов, определенным каким-либо процессом. Это точка , когда вам нужно ограничить данный вызываемый объект.
Ограничение функции на сайте, где вы создаете карризованный вызываемый объект, бесполезно. Вы понятия не имеете, есть ли несоответствие типов между аргументами и возвращаемыми значениями или что-то в этом роде. Вы узнаете это только тогда, когда вам будет предоставлен набор аргументов для вызова вызываемого каррированного объекта. Это то место, где вы можете вычислить аргументы, чтобы в конечном итоге вызвать нужную функцию, так что здесь должно произойти ограничение.