我有以下模板
template<typename T> void f(T t) { }
Run Code Online (Sandbox Code Playgroud)
我想将它的特定专业地址传递给C函数
g(&f<int>);
Run Code Online (Sandbox Code Playgroud)
但是因为我想要是可移植的,我希望"f"的调用约定与C的那个匹配.所以我试验了语言链接如何影响调用约定和发现
C++规范的语言链接部分说
在链接规范中,指定的语言链接适用于所有函数声明符的函数类型,具有外部链接的函数名称,以及在链接规范中声明的具有外部链接的变量名称.
因此,为了防止模板在目标文件中区分不同的专业所需的修改,我去了如下
extern "C" {
/* function name will not be affected */
template<typename T> static void f(T t) { }
}
Run Code Online (Sandbox Code Playgroud)
但它给了我一个编译错误,说模板不能有C语言链接,我认为这意味着它抱怨函数模板的函数类型.事实上,我发现了规范
模板,模板显式特化(14.7.3)和类模板部分特化不应具有C链接
现在我很明显,我们不想改变名称的联系,因为我们依靠改造工作.但是,禁止改变类型链接的原因是什么?它似乎限制我们必须使用C++调用约定; 有人知道原因,是否有一个简单的工作来实现我的初始目标?
我改变了我尝试仅将类型链接到现在的方式,如下所示
extern "C" typedef void ftype(int);
template<typename T>
ftype f;
Run Code Online (Sandbox Code Playgroud)
这很好用.遗憾的是,我没有看到f使用这种技术时的定义方法.但无论如何,我试过没有编译器诊断出这个(试过EDG/comeau,GCC和clang),尽管这看起来和以前完全一样:名称应该没有C语言链接,但只有类型有.
有谁能解释一下?