gpt4 book ai didi

c++ - 如何为非成员和成员函数指针部分特化结构模板

转载 作者:行者123 更新时间:2023-11-27 22:33:02 24 4
gpt4 key购买 nike

我正在做一些涉及函数指针的模板元编程。因为非成员函数指针和成员函数指针的函数类型不同,所以我试图区分两者。此外,我希望指向函数的指针作为非类型模板参数而不是结构中函数的参数提供。到目前为止,这是我尝试过的:

template <typename T, T>
struct register_method;

template <typename R, typename... Args>
struct register_method<R(Args...), R (*method)(Args...)>
{
static R invoke(Args&&... params)
{
return (*method)(std::forward<Args>(params)...);
}
};

template <typename T, typename R, typename... Args>
struct register_method<R(Args...), R (T::*method)(Args...)>
{
static R invoke(T* instance, Args&&... params)
{
return (instance->*method)(std::forward<Args>(params)...);
}
};

但是编译失败(这里只是第一个错误):

prog.cc:14:48: error: 'Args' does not refer to a value
struct register_method<R(Args...), R (*method)(Args...)>
^
prog.cc:13:35: note: declared here
template <typename R, typename... Args>
^

我不太确定它想告诉我什么。我的目标是像这样利用这些对象:

void the_func(float val)
{
std::cout << "the_func called: " << val << "\n";
}

int main()
{
register_method<decltype(&the_func), &the_func>::invoke(50.f);
}

我怎样才能让它工作?如果有机会进行简化,那也很好(例如,如果我可以只将函数指针传递给模板而不是同时执行 decltype,这应该会减少样板代码。

编辑:还想补充一点,我需要对非成员函数和成员函数进行单独专门化的原因不仅仅是函数类型不同。由于我附加到不同功能类型的业务规则,两者之间存在不同的静态状态。为了使问题简单化,我在这里省略了这些细节。

最佳答案

以下是修复代码的方法:

template <typename T, T>
struct register_method;

template <typename R, typename... Args, R (*method)(Args...)>
struct register_method<R (*)(Args...), method>
{
template <typename ...P>
static R invoke(P &&... params)
{
return (*method)(std::forward<P>(params)...);
}
};

template <typename T, typename R, typename... Args, R (T::*method)(Args...)>
struct register_method<R (T::*)(Args...), method>
{
template <typename ...P>
static R invoke(T *instance, P &&... params)
{
return (instance->*method)(std::forward<P>(params)...);
}
};

请注意,您必须引入一个单独的参数包才能使转发引用起作用,因为它们仅在推导模板参数时才起作用。


这是使用 C++17 auto 模板参数的替代解决方案:

template <auto method>
struct register_method;

template <typename R, typename... Args, R (*method)(Args...)>
struct register_method<method>
{
template <typename ...P>
static R invoke(P &&... params)
{
return (*method)(std::forward<P>(params)...);
}
};

template <typename T, typename R, typename... Args, R (T::*method)(Args...)>
struct register_method<method>
{
template <typename ...P>
static R invoke(T *instance, P &&... params)
{
return (instance->*method)(std::forward<P>(params)...);
}
};

关于c++ - 如何为非成员和成员函数指针部分特化结构模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58547472/

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