Igo*_*gor 12 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<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;
}
Run Code Online (Sandbox Code Playgroud)
如果 call_function() 是某个 C 库的接口(动态链接到我的程序),是否可以将指针传递给某个模板函数的特定实例?指向(实例化)模板函数和常规函数的指针之间有什么区别吗?
Use*_*ess 12
如图所示,两个函数都有C++语言联动,一切正常。您不是传递模板函数,而是传递从函数 template 实例化的常规函数。
一旦任何模板被实例化,它就不再是真正的模板,就像实例化一个类给你一个对象,而不是另一个类。
虽然缺少一些东西 - 为了链接 C 程序,您需要将接口导入为extern "C" 并将该链接用于您传递给它的任何函数指针。否则 C 和 C++ 方面可能会在要使用的调用约定上存在分歧,一切都会出错。
由于标准明确表示
模板、模板显式特化和类模板部分特化不应具有 C 链接
我们需要一些解决方法。像往常一样,你的 C 回调接受一个参数,所以没有什么能阻止你在 C 链接蹦床函数中切换调用约定:
extern "C" {
void bounce(void *arg)
{
static_cast<Trampoline *>(arg)->callback();
}
}
Run Code Online (Sandbox Code Playgroud)
wherecallback将是一个普通的 C++ 链接函数,包括一个函数模板实例化(或只是一个std::function或其他)。