获取 C 函数参数的类型

新手上路,请多包涵

是否有标准方法来获取函数参数的类型并将这些类型作为模板参数包传递?我知道这在 C++ 中是可能的,因为 它之前已经完成

我希望使用 C++14 或即将推出的 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 来获取参数类型的名称。但是,我想要实际的类型。不是这些类型的名称。

原文由 Navin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 926
1 个回答

这种语法略有不同。

首先,因为类型比包含包的类型更容易使用。 using type=types; 只是节省了我在生成 types 的代码中的工作:

 template<class...>struct types{using type=types;};

这里是主力。它接受一个签名,并生成一个包含签名参数的 types<?...> 包。 3 个步骤,我们可以获得干净的 C++14esque 语法:

 template<class Sig> struct args;
template<class R, class...Args>
struct args<R(Args...)>:types<Args...>{};
template<class Sig> using args_t=typename args<Sig>::type;

这是语法差异。我们不直接采用 Params... ,而是采用 types<Params...> 。这类似于“标签调度”模式,我们利用模板函数类型推导将参数移动到类型列表中:

 template <class...Params>
void some_function(types<Params...>) {
}

我的 fopen 不同,因为我不想打扰 #include 的东西:

 void* fopen(const char* filename, const char* mode);

并且语法不是基于 fopen ,而是 fopen 的 _类型_。如果您有指针,则需要执行 decltype(*func_ptr) 或类似的操作。或者我们可以增加顶部以处理 R(*)(Args...) 以方便使用:

 template<class Sig>
struct args<Sig*>:args<Sig>{}; // R(*)(Args...) case
template<class Sig>
struct args<Sig&>:args<Sig>{}; // R(&)(Args...) case

然后测试代码:

 int main(){
  some_function(args_t<decltype(fopen)>{});
}

活生生的例子

请注意,这 不适 用于重载函数,也不适用于函数对象。

一般来说,这种事情是个坏主意,因为通常你知道你是如何与一个对象交互的。

如果您想获取一个函数(或函数指针)并从某个堆栈中弹出一些参数并根据预期的参数或类似的参数调用它,上述内容才有用。

原文由 Yakk - Adam Nevraumont 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题