Узнать тип параметра функции

128
17 февраля 2022, 12:40

У меня есть шаблонный параметр, принимающий вызываемый тип. Как узнать тип i-ого параметра этого функционального объекта/функции?

#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <functional>

template<typename Foo>
void print_second_parameter_type() {
    std::cout << typeid(...).name() << '\n';
}

int main() {
    // должно печатать тип второго параметра => typeid(int).name()
    print_second_parameter_type<std::plus<int>>();
}

В документации сказано, что раньше для этого можно было использовать ::second_argument_type конкретно у std::plus<>, но с C++17 это устарело.

Answer 1

Попробуйте так:

template<typename T>
struct extract_value_type { using type = T; };
template<template<typename> class X, typename T>
struct extract_value_type <X<T>> { using type = T; };
template <typename T>
void print_second_parameter_type() {
    std::cout << typeid(typename extract_value_type<T>::type).name() << '\n';
}

Если может встречаться шаблонный шаблонный параметр, то можно сделать рекурсивый обход параметров:

#include <iostream>
#include <type_traits>
template<typename T>
struct extract_value_type { using type = T; };
template<template<typename> class X, typename... Arg>
struct extract_value_type <X<Arg...>> { using type = typename extract_value_type<Arg...>::type; };
template <typename T>
struct X {};
template <typename T>
void print_second_parameter_type() {
    std::cout << typeid(typename extract_value_type<T>::type).name() << '\n';
}
int main() {
    print_second_parameter_type<std::plus<int>>();
    print_second_parameter_type<X<std::plus<int>>>();
    return 0;
}

Но это будет работать, если передаваемый тип имеет только один парметр. Например для print_second_parameter_type<std::vector<std::plus<int>>>(); вывод будет class std::vector<struct std::plus<int>,class std::allocator<struct std::plus<int> > > вместо int

READ ALSO
C++, инициализация constexpr полей

C++, инициализация constexpr полей

Подскажите, пожалуйста, возможно ли инициализировать constexpr член не в хедере, а в файле реализации?

105
C++, constexpr и инициализатор синглтона

C++, constexpr и инициализатор синглтона

Рассмотрим следующий код:

70
Связывание таблиц

Связывание таблиц

Есть таблица:

80
Почему странно работает OR? MySql

Почему странно работает OR? MySql

Запрос составлен следующим образом:

132