首先,让我从我想要做的事情开始。我正在开发一个库,它使得在C ++代码中嵌入Python解释器变得更容易一些,并且我想利用一些C ++ 11特性。我非常使用std :: functions,这是一个问题,因为Python大量使用经典函数指针。
我一直在使用fredbaba的解决方案 https://stackoverflow.com/a/18422878
这可能不是一个好主意,但推理似乎是合理的;对于每个std :: function你也喜欢一个指针,你需要用一个调用感兴趣的std :: function的静态函数创建一些类或结构,任何类函数指针都可以指向静态函数。
然而,这意味着您必须确保创建的每个结构都是唯一的;该线程的海报使用唯一的整数作为标识符,这很麻烦。在我的代码中我使用LINE宏(COUNTER似乎永远不会工作),但课程强制我将所有内容放在一个文件中以避免行号冲突。
我发现了类似的问题,但没有人真的这么做过;为了使其工作,标识符必须是编译时常数,并且我发现的许多解决方案在这方面都失败了。
这可能吗?我可以欺骗系统并获取指向我的std :: functions的指针吗?如果你想知道为什么我需要...我采用一个包含一些C ++函数的std ::函数,在另一个函数中捕获它,然后将它存储在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做了一些事情,但它并不重要。
这是疯了吗?我甚至可以捕获这样的函数吗?约翰
答案 0 :(得分:1)
对于类似的用例(实际上是与JNI一起使用的类工厂),我做了类似的事情。我的技术是在template struct
上使用unsigned
,专门化为0:每个struct
包含一个函数 - 您可以将其调整为static
成员的指针是有效的。我还展示了如何使用依赖于特定特化的参数来调用函数foo
(不确定是否需要此函数,但仅包括在内)。
extern bar* foo(const unsigned& id); // The function that gets called
template<unsigned N> struct Registrar
{
static bar* func()
{
return foo(N - 1);
}
private:
Registrar<N - 1> m_next; // Instantiate the next one.
};
template<> struct Registrar<0> // To block the recursion
{
};
namespace
{
Registrar</*ToDo - total number here*/> TheRegistrar;
}
TheRegistrar
几乎是一个metasyntactic变量,它确保创建给定数量的特化,从而创建static
函数。
(由于各种技术原因,我必须以相反的顺序实例化我的模板:如果您不需要,那么您可以相应地进行调整。)
我认为func
和foo
之间的相互作用是您需要适应您的需求的。当然,每个N
都是您寻找的编译时常量。