考虑到任何仿函数,我想提取它所采用的第一个参数的类型。可以假设仿函数只接受一个参数。我可以用函数来做这件事,但我正在为仿函数寻找解决方案。
#include <iostream>
#include <utility>
template <typename T>
struct test;
template <typename R, typename P>
struct test<R(*)(P)>
{
typedef R R_t;
typedef P P_t;
};
void fn(int value)
{
std::cout << "function called " << value << std::endl;
}
int main()
{
using namespace std;
cout << typeid(test<decltype(&fn)>::R_t).name() << endl;
cout << typeid(test<decltype(&fn)>::P_t).name() << endl;
}
答案 0 :(得分:1)
假设:
template <typename T>
struct member_function_traits;
template <typename C, typename R, typename... Args>
struct member_function_traits<R(C::*)(Args...)> {
using return_type = R;
template <std::size_t i>
struct param {
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
};
};
你可以这样做:
template<typename Functor>
struct functor_traits {
using return_type = typename member_function_traits<decltype(&Functor::operator())>::return_type;
template<std::size_t i>
using param = typename member_function_traits<decltype(&Functor::operator())>::template param<i>;
};
例如,拥有:
struct functor {
void operator()(int) {}
};
以下计划:
std::cout << std::is_same<functor_traits<functor>::return_type, void>::value << std::endl;
std::cout << std::is_same<functor_traits<functor>::param<0>::type, int>::value << std::endl;
会打印:
1
1
答案 1 :(得分:1)
如果你只想要第一个参数类型, 那么你可以使用部分特化,使用可变参数模板来分离第一个参数和其余参数。
我的方法与Jeffery相同,但不使用元组。
template<typename T>
struct member_fn_traits;
template<typename C, typename R, typename First, typename... Rest>
struct member_fn_traits<R (C::*)(First, Rest...)>
{
using first_type = First;
};
template<typename Functor>
struct fn_traits
{
using first_type = typename member_fn_traits<decltype(&Functor::operator())>::first_type;
};
struct functor
{
void operator()(int*, int) {}
};
auto main()
{
auto first_var = fn_traits<functor>::first_type{};
}