使模板函数反映其模板参数的签名
Making a template function mirror its template argument's signature
我有一个模板函数:
template <??? func>
??? wrapper(??? args) {
// ... Stuff
return func(args);
}
它应该与 func
非类型模板参数具有相同的签名。
我得到的最接近的是在模板声明中使用 auto
然后使用某种形式的函数特征来推断 return 类型,但是,这种方法不允许推断整体参数。
理想情况下,
template <typename R, typename... Args, R(*func)(Args...)>
R wrapper(Args&&... args); // ...
或其他一些虚构的语法将 A. 被允许并且 B. 从 func
.
推导出 R
和 Args
func
必须在编译时指定并且函数可以没有任何附加参数(我需要取包装器的地址)。
此时我觉得我现在的解决方案,
template <auto func, typename... Args>
auto wrapper(Args&&... args) {
return func(std::forward<Args>(args)...);
}
无法改进,因为似乎不可能生成“纯”可变参数模板参数(在将它们“存储”到任何地方(例如 tuple
)后取回它们)。这很可悲,因为它强制手动提供 Args
。但我当然希望看到有人证明我在这方面是错误的!
您可以创建特征来提取返回类型和参数。问题是仅从函数声明中处理元数。
如果你能用class/functor包裹起来,那就有可能:
template <auto func> struct wrapper_t;
template <typename Ret, typename ... Ts, Ret (*func)(Ts...)>
struct wrapper_t<func>
{
Ret operator() (Ts... args) const { return func(std::forward<Ts>(args)...); }
};
// handle ellipsis functions ala printf
template <typename Ret, typename ... Ts, Ret (*func)(Ts..., ...)>
struct wrapper_t<func>
{
template <typename ...EllipsisArgs>
Ret operator() (Ts... args, EllipsisArgs&&... ellipisisArgs) const {
return func(std::forward<Ts>(args)...,
std::forward<EllipsisArgs>(ellipisisArgs)...);
}
};
template <auto func>
constexpr wrapper_t<func> wrapper{};
我有一个模板函数:
template <??? func>
??? wrapper(??? args) {
// ... Stuff
return func(args);
}
它应该与 func
非类型模板参数具有相同的签名。
我得到的最接近的是在模板声明中使用 auto
然后使用某种形式的函数特征来推断 return 类型,但是,这种方法不允许推断整体参数。
理想情况下,
template <typename R, typename... Args, R(*func)(Args...)>
R wrapper(Args&&... args); // ...
或其他一些虚构的语法将 A. 被允许并且 B. 从 func
.
R
和 Args
func
必须在编译时指定并且函数可以没有任何附加参数(我需要取包装器的地址)。
此时我觉得我现在的解决方案,
template <auto func, typename... Args>
auto wrapper(Args&&... args) {
return func(std::forward<Args>(args)...);
}
无法改进,因为似乎不可能生成“纯”可变参数模板参数(在将它们“存储”到任何地方(例如 tuple
)后取回它们)。这很可悲,因为它强制手动提供 Args
。但我当然希望看到有人证明我在这方面是错误的!
您可以创建特征来提取返回类型和参数。问题是仅从函数声明中处理元数。
如果你能用class/functor包裹起来,那就有可能:
template <auto func> struct wrapper_t;
template <typename Ret, typename ... Ts, Ret (*func)(Ts...)>
struct wrapper_t<func>
{
Ret operator() (Ts... args) const { return func(std::forward<Ts>(args)...); }
};
// handle ellipsis functions ala printf
template <typename Ret, typename ... Ts, Ret (*func)(Ts..., ...)>
struct wrapper_t<func>
{
template <typename ...EllipsisArgs>
Ret operator() (Ts... args, EllipsisArgs&&... ellipisisArgs) const {
return func(std::forward<Ts>(args)...,
std::forward<EllipsisArgs>(ellipisisArgs)...);
}
};
template <auto func>
constexpr wrapper_t<func> wrapper{};