为什么模板不能在 extern "C" 块中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4877705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't templates be within extern "C" blocks?
提问by Daniel Trebbien
This is a follow-up question to an answerto Is it possible to typedef a pointer-to-extern-“C”-function type within a template?
这是对Is it possible to typedef a pointer-to-extern-“C”-function type in a template?的回答的后续问题?
This code fails to compile with g++
, Visual C/C++, and Comeau C/C++ with basically the same error message:
此代码无法使用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++ says "error: template with C linkage", Visual C/C++ emits compiler error C2894, and Comeau C/C++ says "error: this declaration may not have extern "C" linkage".
g++ 说“错误:带有 C 链接的模板”,Visual C/C++ 发出编译器错误C2894,而 Comeau C/C++ 说“错误:此声明可能没有外部“C”链接”。
The thing is, all are happy with:
问题是,所有人都满意:
#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;
}
Section 7.5, Linkage specifications, of the C++ Standard states:
C++ 标准的第 7.5 节链接规范指出:
A C language linkage is ignored for the names of class members and the member function type of class member functions.
对于类成员的名称和类成员函数的成员函数类型,将忽略 AC 语言链接。
And it even gives the example:
它甚至给出了例子:
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
};
}
If templates were allowed in extern "C" blocks, then the member functions of the instantiations would have C++ linkage.
如果在 extern "C" 块中允许模板,则实例化的成员函数将具有 C++ 链接。
Why, then, does chapter 14, Templates, of the C++98 Standard state:
那么,为什么 C++98 标准的第 14 章模板声明:
A template name may have linkage (3.5). A template, a template explicit specialization (14.7.3), and a class template partial specialization shall not have C linkage.
模板名称可能具有链接 (3.5)。模板、模板显式特化 (14.7.3) 和类模板部分特化不应具有 C 链接。
What does it mean that a template "may" have linkage? What is template linkage?
模板“可能”具有链接是什么意思?什么是模板链接?
Why is it explicitly forbidden to have a template with C linkage, when a class is okay, and all member functions of instantiations of the template (the default constructor, destructor, and assignment operator overload) would have C++ linkage?
为什么明确禁止具有 C 链接的模板,当一个类是好的,并且模板实例化的所有成员函数(默认构造函数、析构函数和赋值运算符重载)都将具有 C++ 链接时?
采纳答案by Fred Nurk
What does it mean that a template "may" have linkage? What is template linkage?
模板“可能”具有链接是什么意思?什么是模板链接?
All names either have external linkage, internal linkage, or have no linkage (C++03 §3.5p2), but this is not the same linkage as language linkage. (Confusing, I know. C++0x changes things around considerably with linkage, too.) External linkage is required for anything used as a template argument:
所有名称要么具有外部链接、内部链接,要么没有链接(C++03 §3.5p2),但这与语言链接不同。(令人困惑,我知道。C++0x 也通过链接改变了很多东西。)用作模板参数的任何东西都需要外部链接:
void f() {
struct S {};
vector<S> v; // Not allowed as S has internal linkage.
}
Notice that C++98 has "may" in what you quoted of §14p4, but C++03 removes the "may", as templates cannot be declared in a context that would give them internal linkage:
请注意,C++98 在您引用的 §14p4 中有“可能”,但 C++03 删除了“可能”,因为模板不能在会给它们提供内部链接的上下文中声明:
void f() {
// Not allowed:
template<class T>
struct S {};
}
回答by Mark Ransom
Templates aren't actual code, they're just guidelines to the compiler for how to generate the code once the template parameters are known. As such they don't actually exist until you try to use them. You can't provide linkage to something that doesn't exist.
模板不是实际的代码,它们只是编译器在知道模板参数后如何生成代码的指南。因此,在您尝试使用它们之前,它们实际上并不存在。你不能提供与不存在的东西的链接。
回答by Frederik Slijkerman
Because template function names need to be decorated with additional information, and extern "C"
turns decoration off. The purpose of extern "C"
is to be able to declare functions that can be called with C linkage, which is something that will never work with a template function obviously.
因为模板函数名称需要用附加信息extern "C"
修饰,并关闭修饰。的目的extern "C"
是能够声明可以使用 C 链接调用的函数,这显然永远不会与模板函数一起使用。
回答by Edward Strange
Because there are no templates in C.
因为 C 中没有模板。