有没有一种标准的方法来获取函数参数的类型,并将这些类型作为模板参数包传递?我知道这在C中是可能的,因为it has been done before。
我希望在C14或即将到来的C++1z中,会有一种惯用的方式来实现arg_types<F>...
:
template <typename ...Params>
void some_function(); // Params = const char* and const char*
FILE* fopen(const char* restrict filename, const char* restrict mode);
int main(){
some_function<arg_types<fopen>...>();
}
只是为了明确,一个声称没有标准方法来做到这一点的答案不是答案。如果没有答案,我宁愿这个问题一直没有答案,直到解决方案被添加到C++500或者直到宇宙的热寂,以先发生的为准:)
编辑:一个被删除的答案指出,我可以使用PRETTY_FUNCTION
来获取参数类型的名称。但是,我想要实际的类型。不是那些类型的名字。
6条答案
按热度按时间gpnt7bae1#
此语法略有不同。
首先,因为类型比包更容易使用,包是一个包含包的类型。
using type=types;
只是在生成types
的代码中节省了我的工作:这是一匹马。它接受一个签名,并生成一个包含签名参数的
types<?...>
包。3个步骤,这样我们就可以得到干净的C++14风格的语法:这是一个语法差异。我们不直接取
Params...
,而是取types<Params...>
。这类似于“标签调度”模式,其中我们利用模板函数类型推导将参数移动到类型列表中:我的
fopen
是不同的,因为我不想打扰#include
的东西:语法不是基于
fopen
,而是基于fopen
的 type。如果你有一个指针,你需要做decltype(*func_ptr)
或类似的事情。或者我们可以增加顶部来处理R(*)(Args...)
,以便于用途:测试代码:
live example。
注意,这不适用于重载函数,也不适用于函数对象。
总的来说,这种事情是一个坏主意,因为通常你知道你是如何与对象交互的。
只有当你想获取一个函数(或函数指针),并从某个堆栈中弹出一些参数,然后根据它所期望的参数调用它,或者类似的事情时,上面的方法才有用。
koaltpgm2#
受@Yakk的启发,这里有一个稍微简化的版本:
1.首先,我们定义了一个帮助 meta函数来将函数的类型存储为元组。
1.我们使用概念来限制输入作为函数
1.下面是我们的函数“arguments”,用于检索输入的参数类型。依赖于输入参数,我们重载“arguments”函数来接受引用和非引用。(自由函数总是通过引用传递。我们甚至不需要函数体,只要返回类型就足够了,因为这是 meta函数。
1.下面是测试:
我的完整版本是here which also supports lambda, functor, member function pointer
jv4diomz3#
使用Boost.FunctionTypes和
std::index_sequence
。下面是一个打印函数func
的参数类型的示例。您可以更改doit
静态函数来执行您想要的操作。在行动中看到它here。标题(移到这里以减少上面代码片段中的噪音):
xu3bshqb4#
对于boost用户,
#include <boost/type_traits.hpp>
Boost Document
tvz2xvvm5#
使用符合C++17(或更高版本)的编译器,您可以使用以下命令:
vs91vp4v6#
几年后,但看到我的完整解决方案here(生产级,完全文档化)。例如,想要某个函数“F”的第二个参数(第二个模板参数是从零开始的):
希望其用户友好的名称为字符串(std::basic_string_view):
根据你最初的问题想要它的所有(非变量)参数(尽管通常很少有人需要直接访问它)。还有一个函数可以循环遍历它们,并在每个arg类型上调用您自己的functor(请参阅上面链接中的“循环遍历所有函数参数”):
其中包括参数计数、返回类型、非静态成员函数上的cv限定符等。
请注意,“F”可以是任何原始C函数类型,函数类型指针,函数类型引用(不包括对C中不法律的的非静态成员函数的引用),函数类型指针引用和仿函数类型(包括lambda)。