没有 __LINE__ 或 __COUNTER__ 宏的唯一模板 Class

Unique Template Class without __LINE__ or __COUNTER__ Macros

首先,让我从我正在尝试做的事情开始。我正在开发一个库,可以更轻松地在 C++ 代码中嵌入 Python 解释器,并且我想利用一些 C++11 功能。我大量使用 std::functions,这是一个问题,因为 Python 大量使用 classic 函数指针。

我一直在使用 fredbaba 的解决方案

这可能不是一个好主意,但推理似乎是合理的;对于每个 std::function 你也想要一个指针,你需要创建一些 class 或带有调用感兴趣的 std::function 和任何 class 函数的静态函数的结构指针可以指向静态函数。

但是,这意味着您必须确保创建的每个结构都是唯一的;该线程的发帖者使用唯一的整数作为标识符,这很麻烦。在我的代码中,我使用了 LINE 宏(COUNTER 似乎从来没有起作用),但是那当然迫使我将所有内容放在一个文件中以避免行号冲突。

我发现有人问过类似的问题,但 none 他们确实做到了;为了让它起作用,标识符必须是一个编译时间常量,我发现的许多解决方案在这方面都失败了。

这可能吗?我可以欺骗系统并获得指向我的 std::functions 的指针吗?如果您想知道为什么我需要...我采用了一个 std::function 来包装一些 C++ 函数,将其捕获在另一个函数中,然后将其存储在 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 做了一些事情,但这并不重要。

这是疯了吗?我什至可以捕获这样的函数吗?

约翰

我为类似的用例做了一些大致相似的事情(实际上是一个 class 用于 JNI 的工厂)。我的技术是在 unsigned 上使用 template struct 并特化为 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 几乎是一个元句法变量,它确保了给定数量的特化,因此创建了 static 函数。

(由于各种技术原因,我必须以相反的顺序实例化我的模板:如果您不需要,可以相应地进行调整。)

我想这是 funcfoo 之间的相互作用,您需要根据自己的需要进行调整。当然,每个 N 都是您要查找的 编译时 常量。