推导函数对象参数类型
Deduce function object argument types
给定一组参数类型和一个函数对象,可以用 decltype
推导出 return 类型。如何推断参数类型?
对于函数指针,return 和参数类型都可以使用有趣的模式匹配语法推导出来。例如,这是一个愚蠢的程序,它使用推导的参数类型打印出描述函数指针的 return 和参数类型的字符串。
#include <iostream>
#include <string>
using std::string;
template<class T>
string type_str();
template<>
string type_str<int>() { return "int"; }
template<>
string type_str<char>() { return "char"; }
string arg_types_str()
{
return "";
}
template<class T>
string arg_types_str()
{
return type_str<T>();
}
template<class T, class U, class... Args>
string arg_types_str()
{
return type_str<T>() + ", " + arg_types_str<U, Args...>();
}
template<class R, class... Args>
void print_fptr_type(R (*fptr)(Args...))
{
std::cout << type_str<R>() << " (*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
int main()
{
int (*fptr)(char, int);
print_fptr_type(fptr);
}
输出:
int (*)(char, int)
是否可以编写类似于示例的程序,而不是打印函数对象的 return 和参数类型?
似乎对于只有一个 operator()
的函数对象,原则上可以明确地推导参数类型。
是的,可以做到。该策略类似,但对于函数对象,它是一个两阶段过程。首先获取指向operator()
的成员函数指针,然后可以使用类似的模式匹配方法进行类型推导。
新程序的关键部分是:
template<class T, class R, class... Args>
void print_memfptr_types(R (T::*memfptr)(Args...))
{
std::cout << type_str<R>() << " (" << type_str<T>() << "*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
template<class T, class R, class... Args>
void print_cmemfptr_types(R (T::*memfptr)(Args...))
{
std::cout << type_str<R>() << " (const " << type_str<T>() << "*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
template<class T>
void print_fnc_obj_types(T&)
{
print_memfptr_types(&T::operator());
}
template<class T>
void print_fnc_obj_types(const T&)
{
print_cmemfptr_types(&T::operator());
}
给定一组参数类型和一个函数对象,可以用 decltype
推导出 return 类型。如何推断参数类型?
对于函数指针,return 和参数类型都可以使用有趣的模式匹配语法推导出来。例如,这是一个愚蠢的程序,它使用推导的参数类型打印出描述函数指针的 return 和参数类型的字符串。
#include <iostream>
#include <string>
using std::string;
template<class T>
string type_str();
template<>
string type_str<int>() { return "int"; }
template<>
string type_str<char>() { return "char"; }
string arg_types_str()
{
return "";
}
template<class T>
string arg_types_str()
{
return type_str<T>();
}
template<class T, class U, class... Args>
string arg_types_str()
{
return type_str<T>() + ", " + arg_types_str<U, Args...>();
}
template<class R, class... Args>
void print_fptr_type(R (*fptr)(Args...))
{
std::cout << type_str<R>() << " (*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
int main()
{
int (*fptr)(char, int);
print_fptr_type(fptr);
}
输出:
int (*)(char, int)
是否可以编写类似于示例的程序,而不是打印函数对象的 return 和参数类型?
似乎对于只有一个 operator()
的函数对象,原则上可以明确地推导参数类型。
是的,可以做到。该策略类似,但对于函数对象,它是一个两阶段过程。首先获取指向operator()
的成员函数指针,然后可以使用类似的模式匹配方法进行类型推导。
新程序的关键部分是:
template<class T, class R, class... Args>
void print_memfptr_types(R (T::*memfptr)(Args...))
{
std::cout << type_str<R>() << " (" << type_str<T>() << "*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
template<class T, class R, class... Args>
void print_cmemfptr_types(R (T::*memfptr)(Args...))
{
std::cout << type_str<R>() << " (const " << type_str<T>() << "*)(" << arg_types_str<Args...>() << ")" << std::endl;
}
template<class T>
void print_fnc_obj_types(T&)
{
print_memfptr_types(&T::operator());
}
template<class T>
void print_fnc_obj_types(const T&)
{
print_cmemfptr_types(&T::operator());
}