C++ 是否允许将指向模板函数的指针传递给C库?(作为回调)

C++ 是否允许将指向模板函数的指针传递给C库?(作为回调),c++,c,templates,metaprogramming,C++,C,Templates,Metaprogramming,考虑以下代码: #include <iostream> struct Foo { void work() { std::cout << "foo" << std::endl; } }; typedef void function_type(void *arg); template <typename T> void function(void *arg) { auto &t = *reinterpret_cast<

考虑以下代码:

#include <iostream>

struct Foo {
  void work() { std::cout << "foo" << std::endl; }  
};

typedef void function_type(void *arg);

template <typename T>
void function(void *arg)
{
    auto &t = *reinterpret_cast<T*>(arg);
    t.work();
}

void call_function(function_type *fn, void *arg)
{
    fn(arg);
}

int main()
{
    Foo foo;

    call_function(&function<Foo>, &foo);

    return 0;
}
#包括
结构Foo{

空函数():代码中的STD::CUT

,两个函数都有C++语言链接,一切都很好。你没有传递模板函数,你正在传递一个从函数模板实例化的正则函数。 一旦任何模板被实例化,它就不再是一个真正的模板,就像实例化一个类给你一个对象,而不是另一个类

<> P>有一个东西丢失了——为了连接C程序,你需要导入接口为<代码>外“C”<代码>,并使用该链接来传递给它的任何函数指针。否则,C和C++双方可能会不同意使用调用约定,并且所有的事情都会发生严重错误。 因为标准明确规定

模板、模板显式专门化和类模板部分专门化不应具有C链接

我们需要一些解决方法。像往常一样,您的C回调函数接受一个参数,因此没有任何东西可以阻止您在C-Link trampoline函数中切换调用约定:

extern "C" {
    void bounce(void *arg)
    {
        static_cast<Trampoline *>(arg)->callback();
    }
}
extern“C”{
无效反弹(无效*arg)
{
静态_cast(arg)->callback();
}
}

其中,
callback
将是一个普通的C++链接函数,包括一个函数模板实例化(或者只是一个
std::function
或其他任何东西).

如果不是,我会感到惊讶。模板函数的实例化不应该与普通函数有所不同。这应该可以工作到最后,模板函数的实例只是函数……换句话说……“不”。您没有传递一个函数,不管它是否从模板实例化。您传递的是一个函数指针。在外部“c”中强制转换非c是否可以?@NooneAtAll是的。仅仅因为它在外部“c”中并不意味着它是c代码,它只意味着代码具有c链接。