受另一个问题的启发,我试图找到一种推断类型的方法 给定用于调用的实际参数的重载成员函数 那个功能。以下是我到目前为止的情况:
#include <type_traits>
template<typename F, typename Arg>
struct mem_fun_type {
// perform overload resolution here
typedef decltype(std::declval<F>()(std::declval<Arg>())) result_type;
typedef decltype(static_cast<result_type (F::*)(Arg)>(&F::operator())) type;
};
struct foo {};
struct takes_two
{
void operator()(int);
void operator()(foo);
};
struct take_one {
void operator()(float);
};
int main()
{
static_assert(std::is_same<mem_fun_type<take_one, float>::type,
void (take_one::*)(float)>::value, "Zonk");
static_assert(std::is_same<mem_fun_type<takes_two, double>::type,
void (takes_two::*)(float)>::value, "Zonk");
return 0;
}
只要模板参数Arg与实际类型匹配即可 static_cast会成功,但这只是最简单的例子 重载分辨率(完全匹配)。是否有可能执行 模板元编程中完整的重载解析过程?
这纯粹是假设的,不适合现实世界使用。
答案 0 :(得分:1)
这是我到目前为止最接近它:定义函数返回不同大小的表,结果是sizeof(select(...))
接收指向要匹配的函数的指针。为了确保即使在给定的类中不存在函数,代码也会编译,您可以使用单独的检查has_function
。
重载解析的结果在select<has_function<T>::value, T>::value
。
使用此代码,您甚至可以“解析”数据成员,而不仅仅是函数,这只是为选择函数创建正确参数的问题。
但是这里存在一个缺陷 - 重载分辨率不是在函数参数上,而是在函数类型上。含义通常不会发生通常的参数类型转换。
// Verify the name is valid
template <typename T>
struct has_function
{
struct F {int function;};
struct D : T, F {};
template <typename U, U> struct same_;
template <typename C> static char(&select_(same_<int F::*, &C::function>*))[1];
template <typename> static char(&select_(...))[2];
enum {value = sizeof(select_<D>(0)) == 2};
};
// Values to report overload results
enum type { none=1 , function_sz_size_t , function_sz , function_string };
template <bool, typename R> struct select;
template <typename R> struct select<false, R>
{
enum {value = none};
};
template <typename R> struct select<true, R>
{
// Define your overloads here, they don't have to be templates.
template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(const char*, Arg)))[function_sz_size_t];
template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(Arg)))[function_sz];
template <typename Ret> static char(&select_(Ret (R::*)(std::string)))[function_string];
template <typename Ret> static char(&select_(Ret (R::*)(std::string&&)))[function_string];
template <typename Ret> static char(&select_(Ret (R::*)(const std::string&)))[function_string];
static char(&select_(...))[none];
enum {value = sizeof(select_(&R::function))};
};