推断 class 拥有成员函数的类型

Infer the type of the class owning a member function

让我们考虑一种“调用”函数(此处称为“调用”),它有助于调用由模板参数传递的成员函数。 在这个函数中,我需要知道拥有成员函数的 class 的类型。有没有办法(最好是在 c++14 中)这样做?

#include <functional>

template<typename F, typename... Args, std::enable_if_t<std::is_member_pointer<std::decay_t<F>>{}, int> = 0 >
constexpr decltype(auto) call(F&& f, Args&&... args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
{
    // Here we know that f is a member function, so it is of form : &some_class::some_function
    // Is there a way here to infer the type some_class from f ? For exemple to instantiate a variable from it :
    // imaginary c++ : class_of(f) var;
    return std::mem_fn(f)(std::forward<Args>(args)...);
}

int main()
{
    struct Foo { void bar() {} } foo;
    call(&Foo::bar, &foo /*, args*/);
    return 0;
}
template <typename>
struct class_of;
template <typename C, typename R, typename... Args>
struct class_of<R(C::*)(Args...)> {
    using type = C;
};

然后就可以得到typename class_of<F>::type这样的类型了。例如

template<typename F, typename... Args, std::enable_if_t<std::is_member_pointer<std::decay_t<F>>{}, int> = 0 >
constexpr decltype(auto) call(F&& f, Args&&... args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
{
    typename class_of<F>::type var;
    return std::mem_fn(f)(std::forward<Args>(args)...);
}

顺便说一句,这取决于您的意图,但您可以更改模板参数的声明以直接获取 class 类型。

// I remove the type check because only member function pointer could be passed in
template<typename C, typename R, typename... FArgs, typename... Args>
constexpr decltype(auto) call(R(C::*f)(FArgs...), Args&&... args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
{
    C var;
    return std::mem_fn(f)(std::forward<Args>(args)...);
}

打败了我,但请注意,您不需要拼出函数类型来解构成员指针:

template <class MemberPtr>
struct mptr_class;

template <class T, class Class>
struct mptr_class<T Class::*> {
    using type = Class;
};

template <class MemberPtr>
using mptr_class_t = typename mptr_class<MemberPtr>::type;