【发布时间】:2015-09-29 14:03:21
【问题描述】:
首先,让我从我正在尝试做的事情开始。我正在开发一个库,使在 C++ 代码中嵌入 Python 解释器更容易一些,我想利用一些 C++11 功能。我大量使用 std::functions ,这是一个问题,因为 Python 大量使用经典函数指针。
我一直在使用 fredbaba 的解决方案,该解决方案位于 https://stackoverflow.com/a/18422878
这可能不是一个好主意,但推理似乎是合理的;对于您也想要一个指针的每个 std::function,您需要创建一些类或结构,其中包含一个调用感兴趣的 std::function 的静态函数,并且任何类函数指针都可以指向静态函数。
但是,这意味着您必须确保创建的每个结构都是唯一的;该线程的海报使用唯一整数作为标识符,这很麻烦。在我的代码中,我使用了 LINE 宏(COUNTER 似乎从不工作),但课程迫使我将所有内容放在一个文件中以避免行号冲突。
我发现有人问过类似的问题,但他们都没有真正做到;为了使它工作,标识符必须是编译时间常数,我发现的许多解决方案在这方面都失败了。
这可能吗?我可以欺骗系统并获得指向我的 std::functions 的指针吗?如果您想知道为什么我需要... 我采用一个包装了一些 C++ 函数的 std::function,将其捕获到另一个函数中,然后将其存储在 std::list 中。然后我为每个列表元素创建一个函数指针,并将它们放入我创建的 Python 模块中。
// Store these where references are safe
using PyFunc = std::function<PyObject *(PyObject *, PyObject *)>;
std::list<PyFunc> lst_ExposedFuncs;
...
// Expose some R fn(Args...){ ... return R(); }
template <size_t idx, typename R, typename ... Args>
static void Register_Function(std::string methodName, std::function<R(Args...)> fn, std::string docs = "")
{
// Capture the function you'd like to expose in a PyFunc
PyFunc pFn = [fn](PyObject * s, PyObject * a)
{
// Convert the arguments to a std::tuple
std::tuple<Args...> tup;
convert(a, tup);
// Invoke the function with a tuple
R rVal = call<R>(fn, tup);
// Convert rVal to some PyObject and return
return alloc_pyobject(rVal);
};
// Use the unique idx here, where I'll need the function pointer
lst_ExposedFunctions.push_back(pFn);
PyCFunction fnPtr = get_fn_ptr<idx>(lst_ExposedFunctions.back());
}
从那时起,我实际上用 fnPtr 做了一些事情,但这并不重要。
这很疯狂吗?我什至可以捕获这样的函数吗?
约翰
【问题讨论】:
-
您可以使用类型而不是数字进行标记。就像
Register_Function<struct MyMethod_tag>("MyMethod", ...);一样,通常想出一个唯一的类型名称比使用一个唯一的编号更容易。请注意,您实际上不需要定义MyMethod_tag- 精心制作的类型说明符兼作前向声明,这就是所需要的。 -
这是一个有趣的解决方案,我可能会接受。这似乎有点冗长,但我想一个优点是您可以将一些信息编码到标签结构的名称中。谢谢!
-
这是伊戈尔所说的一个例子......我想。 ideone.com/zLYETM
标签: c++ c++11 function-pointers template-meta-programming