问题描述
我正在尝试编写一个通用包装器,用于从 C++ 驱动程序构建 Python 函数。首先,我希望能够使用一些模板魔术来生成关联的 ctypes
并能够打印它们。我有一切工作,但我似乎无法将函数签名类型拉上一层,这违背了目的......
我目前在 godbolt 上对该问题进行了以下最小复制:
#include <functional>
#include <iostream>
template <typename T>
struct ctype
{
using type = void*;
static constexpr char name[] = "c_void_p";
};
template <>
struct ctype<int>
{
static constexpr char name[] = "c_int";
};
template <>
struct ctype<double>
{
static constexpr char name[] = "c_double";
};
template<typename T>
struct function_traits;
template<typename R,typename ...Args>
struct function_traits<std::function<R(Args...)>>
{
static constexpr size_t nargs = sizeof...(Args);
using result_ctype = ctype<R>;
template <size_t i>
using arg_ctype = ctype<typename std::tuple_element<i,std::tuple<Args...>>::type>;
};
template <typename FuncSignature>
void log_function_signature()
{
// using function_proto = function_traits<std::function<double(double,int)>>; // OK
using function_proto = function_traits<std::function<FuncSignature>>; // BAD? Why?
std::cout << function_proto::result_ctype::name << std::endl;
std::cout << function_proto::arg_ctype<0>::name << std::endl;
std::cout << function_proto::arg_ctype<1>::name << std::endl;
}
double foobar(double x,int y)
{
return x * y;
}
int main() {
log_function_signature<double(double,int)>();
}
function_traits
改编自此答案:https://stackoverflow.com/a/9065203/2242096。理想情况下,我会直接在 FuncSignature
内使用 log_function_signature
,但我无法弄清楚为什么这是不允许的。编译器给了我以下内容:
<source>: In function 'void log_function_signature()':
<source>:42:48: error: '::name' has not been declared; did you mean 'rename'?
42 | std::cout << function_proto::arg_ctype<0>::name << std::endl;
| ^~~~
| rename
<source>:43:48: error: '::name' has not been declared; did you mean 'rename'?
43 | std::cout << function_proto::arg_ctype<1>::name << std::endl;
| ^~~~
| rename
<source>: In instantiation of 'void log_function_signature() [with FuncSignature = double(double,int)]':
<source>:52:48: required from here
<source>:42:34: error: dependent-name 'function_proto::arg_ctype' is parsed as a non-type,but instantiation yields a type
42 | std::cout << function_proto::arg_ctype<0>::name << std::endl;
| ^~~~~~~~~
<source>:42:34: note: say 'typename function_proto::arg_ctype' if a type is meant
<source>:43:34: error: dependent-name 'function_proto::arg_ctype' is parsed as a non-type,but instantiation yields a type
43 | std::cout << function_proto::arg_ctype<1>::name << std::endl;
| ^~~~~~~~~
<source>:43:34: note: say 'typename function_proto::arg_ctype' if a type is meant
ASM generation compiler returned: 1
<source>: In function 'void log_function_signature()':
<source>:42:48: error: '::name' has not been declared; did you mean 'rename'?
42 | std::cout << function_proto::arg_ctype<0>::name << std::endl;
| ^~~~
| rename
<source>:43:48: error: '::name' has not been declared; did you mean 'rename'?
43 | std::cout << function_proto::arg_ctype<1>::name << std::endl;
| ^~~~
| rename
<source>: In instantiation of 'void log_function_signature() [with FuncSignature = double(double,but instantiation yields a type
43 | std::cout << function_proto::arg_ctype<1>::name << std::endl;
| ^~~~~~~~~
<source>:43:34: note: say 'typename function_proto::arg_ctype' if a type is meant
Execution build compiler returned: 1
为什么模板类型在函数内部编写时有效,而通过模板传入时无效?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)