Есть ли declval для указателей функций? - PullRequest
0 голосов
/ 01 марта 2019

У меня есть функция, и мне нужно проверить, могу ли я передать ей аргумент заданного типа.Например:

template<typename T, auto F>
decltype(F(declval<T>{})) foo();

Вызов foo<int, bar>() делает 2 вещи:

  1. Устанавливает тип возврата foo будет иметь тот же тип возврата, что и bar
  2. Гарантирует, что bar - это функция, которая принимает аргумент типа T

К сожалению, у меня нет доступа к auto типам шаблонов, но я все еще хочу выполнить обаиз этих.Мне нужен decltype для указателей на функции, который позволил бы мне сделать что-то вроде этого:

template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();

Так что я все еще мог бы вызвать foo<int, bar>() и получить тот же результат,Конечно, для указателей на функции нет declval.Но есть ли другой способ, которым я мог бы сделать это?

1 Ответ

0 голосов
/ 01 марта 2019

Конечно, для указателей на функции нет declval.

Что вы имеете в виду?std::declval отлично работает с типами указателей на функции:

template<typename F, typename... Args>
using call_t = decltype(std::declval<F>()(std::declval<Args>()...));

В этом примере F может быть типом указателя на функцию, лямбда-типом или любыми вызываемыми типами.

Вот примериспользования:

template<typename T, typename F>
auto foo() -> call_t<F, T>;

Другой пример использования идиомы обнаружения (реализуемой в C ++ 11):

template<typename F, typename... Args>
using is_callable = is_detected<call_t, F, Args...>;

static_assert(is_callable<void(*)(int), int>::value, "callable")

Обратите внимание, что все это можно заменить на std::invoke_result_tи std::is_invocable в C ++ 17.Я бы посоветовал имитировать их, чтобы получить наиболее плавное обновление.

...