模板外部链接?任何人都可以解释这个? [英] template External Linkage ?can anyone Explain this?

查看:277
本文介绍了模板外部链接?任何人都可以解释这个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


模板名称具有链接(3.5)。非成员函数模板可以具有内部链接;任何其他模板名称应具有外部链接。从内部链接的模板生成的实体与其他翻译单元生成的所有实体不同。


我知道使用关键字

  externC

EX:

  externC{template< class T& class X {}; } 

但他们给予模板不应具有C链接



可以解释这一点吗?

c> c> c> c> 这与外部链接内部链接不同。默认情况下,C ++程序中的所有内容都具有C ++语言链接,尽管你可以通过指定 externC ++来重申。



外部链接意味着该名称对于单独编译的其他源文件可见,假设您包含正确的标头或提供正确的声明。这是允许您在 a.cpp 中定义一个函数 foo ,并从 b.cpp 。 C ++程序中命名空间范围中的大多数名称都具有外部链接。例外是内部链接,以及无链接。您可以通过指定 extern 来将某个内容显式标记为具有外部链接。这与 externC不同。



内部链接对当前编译单元是唯一的,并且您不能从另一个源文件访问变量或函数。文件范围变量和声明为 static 的函数具有内部链接。此外,使用常量表达式初始化的命名空间范围中的 const 整数变量默认具有内部链接,但您可以使用显式 extern



最后,局部变量和类具有无关联。这些名称是它们在其中声明的函数的本地,并且不能从该函数外部访问。您可以使用 extern 表示您确实想要访问命名空间范围的变量。



无法定义模板在本地范围,但可以有内部或外部链接。

  int i; //命名空间范围变量具有外部链接
extern int j; //用外部链接显式标记j
static int k; // k有内部链接
int const n = 42; // internal linkage
extern int const m = 99; // external linkage

void foo(); // foo有外部链接它可以在这个源文件或另一个
extern void foo()中定义; //用外部链接显式标记foo
static void bar(); // bar有内部链接,并且必须在此源文件中定义

void foo(){} // foo的定义,从其他源文件可见
void bar(){} //定义bar,不能从其他源文件(内部链接)看到

static void baz(){} //声明并定义带有内部链接的baz

template<类型名T> void foobar(){} // foobar有外部链接
template< typename T>
static void foobaz(){} // foobaz有内部链接

void wibble()
{
int i; // local,no linkage
extern int i; //引用i,上面用外部链接声明
}

externC
{
int i2; //命名空间作用域变量具有外部链接和C链接
extern int j2; //用外部链接和C链接显式标记j2
static int k2; // k2有内部链接和C链接
int const n2 = 42; //内部链接和C链接
extern int const m2 = 99; //外部链接和C链接

void foo2(); // foo2有外部链接和C链接
static void bar2(); // bar2有内部链接和C链接

void foo2(){} //定义foo2,仍然使用外部链接和C链接
void bar2 //定义bar2,仍然具有内部链接和C链接

static void baz(){} //使用内部链接声明和定义baz
}

错误讯息正确---模板不能有 externC链接。



在基本层面,模板不能具有 externC C.具体来说,模板不只是定义一个类或函数,而是一组共同拥有相同名称但通过模板参数区分的类或函数。



只有一个具有给定名称的函数可以声明为 externC。这是有道理的,当你考虑名称mangling ---在C中,函数 foo 通常被称为 foo 或符号表中的 _foo 。在C ++中,可能有许多重载 foo ,所以签名被合并到符号表中的mangled名称中,你可能会得到 $ 3 fooV foo $ void 或其他东西来区分 foo(void) c $ c> foo(int)等等。在C ++中,标记为 externC的单个重载根据给定平台的C方案被破坏,而其他重载保持它们的正常名称。 p>

声明模板 externC将需要所有实例化 externC / code>,因此与只有一个具有给定名称的函数可以是 externC规则相矛盾。



虽然C对于 struct 没有名称调整,但只能有一个 struct 与给定的名称。因此,对类模板禁止 externC也是有意义的 - 模板定义了一组具有相同名称的类,因此一个对应于C struct


A template name has linkage (3.5). A non-member function template can have internal linkage; any other template name shall have external linkage. Entities generated from a template with internal linkage are distinct from all entities generated in other translation units.

I know about external linkage using the keyword

extern "C"

EX :

extern "C" {   template<class T>  class X { };   }

but they gave template shall not have a C linkage

what actually meant for the above statement?

can any one explain this ?

解决方案

extern "C" declares something to have C language linkage. This is different from external linkage and internal linkage. By default, everything in a C++ program has C++ language linkage, though you can reiterate that by specifying extern "C++".

external linkage means that the name is visible to other source files compiled separately, assuming you include the right headers or provide the right declarations. This is what allows you to define a function foo in a.cpp, and call it from b.cpp. Most names at namespace scope in a C++ program have external linkage. The exceptions are those that have internal linkage, and those that have no linkage. You can explicitly mark something as having external linkage by specifying extern. This is distinct from extern "C".

internal linkage means that the name is unique to the current compilation unit, and you cannot access the variable or function from another source file. File scope variables and functions declared static have internal linkage. Also, const integer variables at namespace scope that are initialized with a constant expression have internal linkage by default, though you can override it with an explicit extern.

Finally, local variables and classes have no linkage. The names are local to the function they are declared in, and cannot be accessed from outside that function. You can use extern to indicate that you really want to access a variable at namespace scope.

Templates cannot be defined at local scope, but may have either internal or external linkage.

int i; // namespace scope variable has external linkage
extern int j; // explicitly mark j with external linkage
static int k; // k has internal linkage
int const n=42; // internal linkage
extern int const m=99; // external linkage

void foo(); // foo has external linkage; it may be defined in this source file or another
extern void foo(); // explicitly mark foo with external linkage
static void bar(); // bar has internal linkage, and must be defined in this source file

void foo(){} // definition of foo, visible from other source files
void bar(){} // definition of bar, not visible from other source files (internal linkage)

static void baz(){} // declare and define baz with internal linkage

template<typename T> void foobar(){} // foobar has external linkage
template<typename T>
static void foobaz(){} // foobaz has internal linkage

void wibble()
{
    int i; // local, no linkage
    extern int i; // references i, declared above with external linkage
}

extern "C"
{
    int i2; // namespace scope variable has external linkage, and "C" linkage
    extern int j2; // explicitly mark j2 with external linkage and "C" linkage
    static int k2; // k2 has internal linkage and "C" linkage
    int const n2=42; // internal linkage and "C" linkage
    extern int const m2=99; // external linkage and "C" linkage

    void foo2(); // foo2 has external linkage and "C" linkage
    static void bar2(); // bar2 has internal linkage and "C" linkage

    void foo2(){} // definition of foo2, still with external linkage and "C" linkage
    void bar2(){} // definition of bar2, still with internal linkage and "C" linkage

    static void baz(){} // declare and define baz with internal linkage
}

The error message is correct --- templates cannot have extern "C" linkage.

At the basic level, templates cannot have extern "C" linkage because they are not compatible with C. In particular, a template doesn't just define a single class or function, but a family of classes or functions that share the same name, but are distinguished by their template parameters.

Only one function with a given name may be declared extern "C". This makes sense when you think about the name mangling --- in C, a function foo is typically called either foo or _foo in the symbol table. In C++ there may be many overloads of foo, so the signature is incorporated in the "mangled" name in the symbol table, and you might get $3fooV or foo$void or something else to distinguish foo(void) from foo(int) and so forth. In C++, the single overload that is marked extern "C" gets mangled according to the C scheme for the given platform, whereas the other overloads keep their normal mangled name.

Declaring a template extern "C" would require all instantiations to be extern "C", which thus contradicts the "only one function with a given name can be extern "C"" rule.

Though C doesn't have name mangling for structs, there can only be one struct with a given name. The ban on extern "C" for class templates thus also makes sense --- a template defines a family of classes with the same name, so which one corresponds to the C struct?

这篇关于模板外部链接?任何人都可以解释这个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆