gpt4 book ai didi

c++ - 具有单个参数模板的成员函数包装器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:43 24 4
gpt4 key购买 nike

我做了一个模板函数,它接受一个成员函数作为参数。

但是,由于类必须先声明才能用作成员函数参数的一部分,因此我必须将其作为一个单独的参数:

template<typename C, void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}

这意味着当显式实例化模板时(我希望这些包装器在编译时生成,而不是将成员指针作为参数传递)我在使用它时必须输入两次:

function<void(C*)> someFunc = wrapMethod<SomeClass, &SomeClass::someMethod>();

为什么我不能写这样的东西:

template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}

并让它捕获 C 的类型及其成员函数指针,而无需键入两次 SomeClass?

或者为什么我不能将它包装在一个将 C 声明为“自由变量”然后具有执行推导的内部模板参数的外部模板中

template<typename C>
template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}

最佳答案

如果您可以接受成员函数指针的普通函数参数而不是将其设为模板参数,您可以这样做

#include <functional>

template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
typedef R Return;
typedef C Class;
};

template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)())
{
return MemberFunctionPointer<R,C>{};
}

template<typename T>
constexpr auto methodWrap(T m)
{
typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;

return std::function<Return (Class*)>();
}

struct B {};

struct A
{
B f();
};

void foo()
{
auto const m = methodWrap( &A::f );
}

std::function 不是 constexpr 类型,因此我们不能使用 methodWrap 来初始化 constexpr 变量。您可以通过创建自己的简单 constexpr 成员函数包装器来绕过它。我还添加了 static_assert 以获得更好的错误消息。

#include <functional>

template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
typedef R Return;
typedef C Class;
};

template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)() const)
{
return MemberFunctionPointer<R,C>{};
}

template<typename R, typename C>
struct MemberFunction
{
constexpr explicit MemberFunction(R (C::*g)() const): f(g) {}

constexpr R operator()(C const* obj) const
{
return (obj->*f)();
}

R (C::*f)() const;
};

template<typename T>
constexpr auto methodWrap(T m)
{
static_assert( std::is_member_function_pointer<T>::value,
"Member function pointer expected!");

typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;

return MemberFunction<Return, Class>{ MemberFunctionPointer<Return,Class>{} };
}

struct B {};

struct A
{
constexpr B f() const;
};

void foo()
{
auto constexpr m = methodWrap( &A::f );
auto constexpr a = A{};
m( &a );

auto b = A{};
m( &b );
}

关于c++ - 具有单个参数模板的成员函数包装器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34324091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com