У меня есть шаблонный параметр, принимающий вызываемый тип. Как узнать тип 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
это устарело.
Попробуйте так:
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
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Подскажите, пожалуйста, возможно ли инициализировать constexpr член не в хедере, а в файле реализации?