【发布时间】:2011-02-02 17:30:55
【问题描述】:
这是an answer 到Is it possible to typedef a pointer-to-extern-“C”-function type within a template? 的后续问题
此代码无法使用g++、Visual C/C++ 和 Comeau C/C++ 编译,错误消息基本相同:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
template <typename return_t_, typename arg1_t_>
struct test {
static void foo(return_t_ (*)(arg1_t_)) { }
};
}
int main()
{
test<int, int>::foo(&do_stuff);
return EXIT_SUCCESS;
}
g++ 说“错误:带有 C 链接的模板”,Visual C/C++ 发出编译器错误C2894,Comeau C/C++ 说“错误:此声明可能没有外部“C”链接”。
事实是,所有人都很高兴:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
struct test {
static void foo(int (*)(int)) { }
};
}
int main()
{
test::foo(&do_stuff);
return EXIT_SUCCESS;
}
C++ 标准第 7.5 节,链接规范指出:
类成员和成员函数的名称忽略 C 语言链接 类成员函数的类型。
它甚至给出了例子:
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function's type have C++ language linkage
void mf2(void(*)()); // the name of the function mf2 has C++ language
// linkage; the parameter has type pointer to C function
};
}
如果外部“C”块中允许使用模板,则实例化的成员函数将具有 C++ 链接。
那么,为什么 C++98 标准的第 14 章“模板”状态:
模板名称可能有链接 (3.5)。模板、模板显式特化 (14.7.3) 和类模板部分特化不应具有 C 链接。
模板“可能”有链接是什么意思?什么是模板链接?
当一个类没问题并且模板实例化的所有成员函数(默认构造函数、析构函数和赋值运算符重载)都具有 C++ 链接时,为什么明确禁止具有 C 链接的模板?
【问题讨论】:
-
啊,你找到了禁止模板有C链接的条款!
标签: c++ templates extern linkage