gpt4 book ai didi

c++ - Variadic 模板参数顺序问题

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:42 26 4
gpt4 key购买 nike

我有一个模板化函数包装器,我正在尝试将其更新为 C++11 语法(可变参数)。

我的问题是我陷入了“第 22 条军规”,其中 'Args...' 必须是最后一个模板参数,但同时不能在函数指针之后定义模板参数。

知道这是否真的可以解决吗?

  template <typename... Args, void(*Function)(Args...)>
class function
{
public:

void operator ()(Args... args) const
{
(*Function)(std::forward<Args...>(args...));
}
};

最佳答案

一种可能的方法是使用模板特化

template <typename>
struct myFunc;

template <typename R, typename ... Args>
struct myFunc<R(*)(Args...)>
{
// ...
};

但是,通过这种方式,您拦截(作为模板参数)函数指针的类型,而不是函数指针本身;所以你必须以某种方式传递函数指针(构造函数?)。

还要注意,如果你想使用完美转发,你必须在模板方法中转换 operator() 接收参数作为通用引用 (&&)。

内容如下

   template <typename ... As>
R operator() (As && ... args) const
{
return fun(std::forward<As>(args)...);
}

其中 fun 是类型为 R(*)(Args...) 的指针。

下面是一个完整的编译示例

#include <iostream>
#include <utility>

int foo (int, long)
{ return 42; }

template <typename>
struct myFunc;

template <typename R, typename ... Args>
struct myFunc<R(*)(Args...)>
{
using funPnt = R(*)(Args...);

funPnt fun = nullptr;

myFunc (funPnt f0) : fun{f0}
{ }

template <typename ... As>
R operator() (As && ... args) const
{
return fun(std::forward<As>(args)...);
}
};

int main ()
{
myFunc<decltype(&foo)> mf0{&foo};

std::cout << mf0(1, 2l) << std::endl;
}

如果你真的想要指针函数作为模板参数(但是,这样,每个函数确定不同的类型;根据你的需要,这可能是好事也可能是坏事),你可以编写 myFunc struct 在类型(相同的指针类型)之前接收,然后是该类型的值。

所以

template <typename T, T>
struct myFunc;

template <typename R, typename ... Args, R(*Func)(Args...)>
struct myFunc<R(*)(Args...), Func>
{
template <typename ... As>
R operator() (As && ... args) const
{
return Func(std::forward<As>(args)...);
}
};

可以声明

 myFunc<decltype(&foo), foo>  mf0;

如果你可以使用 C++17,你可以简化使用 auto 作为模板值的类型;这样你就可以避免类型

template <auto>
struct myFunc;

template <typename R, typename ... Args, R(*Func)(Args...)>
struct myFunc<Func>
{
template <typename ... As>
R operator() (As && ... args) const
{
return Func(std::forward<As>(args)...);
}
};

你可以创建一个 myFunc 对象,如下所示

myFunc<&foo> mf0;

补充:如果你会用C++17,你可以为第一个例子定义一个推导指南(指针作为成员,而不是模板值参数)

template <typename R, typename ... Args>
myFunc (R(*)(Args...)) -> myFunc<R(*)(Args...)>;

所以,而不是

myFunc<decltype(&foo)>  mf0{&foo};

你可以简单地写

myFunc  mf0{&foo};

题外话:我希望你知道你正在重新发明轮子。正如 NathanOliver 所建议的,该标准提供了 std::function

关于c++ - Variadic 模板参数顺序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54814157/

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