C ++ извлечь аргумент из сигнатуры функции - PullRequest
0 голосов
/ 02 марта 2019

Учитывая шаблонную функцию подписи

template <typename F>
void fn(F f);

Я хотел бы извлечь пакет параметров данной подписи функции F, если бы вызываемой функции было присвоено fn().

В отличие от foo0() Я не могу сделать это в foo1() и foo2() в следующем примере (упрощено до одного параметра вместо пакета параметров):

#include <type_traits>

template <typename Sig> struct argument_of;
template <typename R, typename Arg> struct argument_of<R(Arg)> { typedef Arg type; };

void bar(int);

void foo0() {
    static_assert(std::is_same<int, typename argument_of<decltype(bar)>::type>::value, "!");
}

template <typename F>
void foo1(F) {
    static_assert(std::is_same<int, typename argument_of<F>::type>::value, "!");
}

template <typename F>
void foo2(F f) {
    static_assert(std::is_same<int, typename argument_of<decltype(f)>::type>::value, "!");
}

int main() {
    foo0();
    foo1(bar);
    foo2(bar);
}

См. live пример.

Что будет правильным, если стиль вызова fn() останется таким, как задано для foo1() и foo2() в примере выше?

1 Ответ

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

Вам также нужна специализация для обработки типа указателя на функцию:

template <typename Sig> struct argument_of;
template <typename R, typename Arg> struct argument_of<R(Arg)> { typedef Arg type; };
template <typename R, typename Arg> struct argument_of<R(*)(Arg)> { typedef Arg type; };

Это небольшое отличие, и я надеюсь, что я правильно понял терминологию, но символ bar - это не перегруженная функция типа void(int), тогда как переменная f (или безымянный F -параметр) является указателем на функцию типа void(*)(int).Переменные и функции принципиально отличаются в C ++, и система типов имеет это различие.

Стоит также отметить, что другой вариант, для которого вы, возможно, захотите специализироваться, - это ссылка на функцию , которая выглядиткак void(&)(int).Тип ссылки на функцию может быть выведен в таких ситуациях, как decltype(*f) или decltype((bar)) (обратите внимание на дополнительные скобки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...