C++11:计算可变参数函数参数类型
假设您要编写一个函数,该函数将不透明句柄传递给未知类型的函数(例如,包含具有商定名称的函数的结构的名称),并将参数转发给该函数。
在非可变参数的情况下,为了简单起见,考虑单参数函数,有两种方法可以做到这一点:您可以让转发函数接受任意类型的参数,并尝试用它调用转发者函数,编译器会抱怨在模板扩展期间如果发现不兼容;或者您可以使用 decltype 和各种其他机制来确定转发者函数期望的参数类型,并明确要求该类型的参数。我不知道这些是否有任何公认的术语,所以我将它们称为“通过”和“预先”。
传递方法可以直接推广到具有任意数量参数的函数,但前面的方法则不然。
#include <iostream>
template<typename T, typename Arg>
void pass_through_1(Arg arg)
{
T::f(arg);
}
template<typename T> struct arg_of_1;
template<typename Ret, typename Arg>
struct arg_of_1<Ret (Arg)>
{
typedef Arg type;
};
template<typename T>
void up_front_1(typename arg_of_1<decltype(T::f)>::type arg)
{
T::f(arg);
}
template<typename T, typename... Args>
void pass_through_var(Args... args)
{
T::f(args...);
}
template<typename T> struct args_of_var;
template<typename...> struct type_list;
template<typename Ret, typename... Args>
struct args_of_var<Ret (Args...)>
{
// typedef Args... type; // can't do this
typedef type_list<Args...> type;
};
// template<typename T>
// void up_front_var(typename args_of_var<decltype(T::f)>::type... args) // can't do this
// {
// T::f(args...);
// }
struct test
{
static void f(int x) { std::cout << x*9 << std::endl; }
};
int main(int, char**)
{
pass_through_1<test>(7);
up_front_1<test>(8);
pass_through_var<test>(9);
// up_front_var<test>(10);
return 0;
}
问题是参数包不允许独立存在,只能作为模板参数,如果将它们包装在封闭的模板中,则无法将它们解开并解开,只能通过模式匹配。
“Up front”具有一些优点,例如更好的自文档以及对类型推断的更好支持(up_front
Let's say you want to write a function which gets passed an opaque handle to a function of unknown type (say, the name of a struct containing a function with an agreed-upon name), and forwards arguments to that function.
In the non-variadic case, considering single-parameter functions for simplicity, there's two ways to do this: you can let the forwarding function take an argument of arbitrary type, and attempt to call the forwardee function with it, and the compiler will complain during template expansion if it turns out to be incompatible; or you can use decltype and assorted other mechanisms to figure out what type of parameter the forwardee function expects, and explicitly require an argument of that type. I don't know if there's any accepted terminology for these, so I'm going to call them "pass through" and "up front".
The pass through method generalizes straightforwardly to functions with an arbitrary number of parameters, but the up front method doesn't.
#include <iostream>
template<typename T, typename Arg>
void pass_through_1(Arg arg)
{
T::f(arg);
}
template<typename T> struct arg_of_1;
template<typename Ret, typename Arg>
struct arg_of_1<Ret (Arg)>
{
typedef Arg type;
};
template<typename T>
void up_front_1(typename arg_of_1<decltype(T::f)>::type arg)
{
T::f(arg);
}
template<typename T, typename... Args>
void pass_through_var(Args... args)
{
T::f(args...);
}
template<typename T> struct args_of_var;
template<typename...> struct type_list;
template<typename Ret, typename... Args>
struct args_of_var<Ret (Args...)>
{
// typedef Args... type; // can't do this
typedef type_list<Args...> type;
};
// template<typename T>
// void up_front_var(typename args_of_var<decltype(T::f)>::type... args) // can't do this
// {
// T::f(args...);
// }
struct test
{
static void f(int x) { std::cout << x*9 << std::endl; }
};
int main(int, char**)
{
pass_through_1<test>(7);
up_front_1<test>(8);
pass_through_var<test>(9);
// up_front_var<test>(10);
return 0;
}
The problem is that parameter packs aren't allowed to be free-standing, only as template arguments, and if you wrap them in an enclosing template, there's no way to unwrap-and-unpack them in place, only by pattern matching.
"Up front" has some advantages like better self-documentation, and better support for type inference (up_front<T> can itself be decltyped). Is there any way to make it work in the variadic case? (You could of course use std::tuple, but that's rather unsatisfying.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有什么比写下问题更能让你找到答案了。
这是一种方法:
我认为没有办法从中创建一个顶级函数(您再次遇到原始问题),但这可能还不错。
仍然很高兴看到其他解决方案。
There's nothing like writing down the question to make you realize the answer.
Here's one way:
I don't think there's a way to make a top-level function out of this (you run into the original problem again), but that's possibly not too bad.
Would still be happy to see other solutions.
也许我没有正确理解这个问题,但你总是可以省略参数类型并让编译器推断它们。
Maybe I'm not understanding the question correctly, but you can always leave out the argument types and let the compiler infer them.