C++ 类主体外的模板定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10211273/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:45:11  来源:igfitidea点击:

Template definitions outside class body

c++templatesvirtualinline

提问by doc

Is it O.K. to define virtual function of class template outside its body? Virtual function can not be inlined, but to avoid multiple definitions in compilation units they shall be marked inline(assuming that template headers will be included in multiple source files). On the other hand compiler is free to ignore inline, so this seems valid. By an example, is the code below correct:

是否可以在其主体之外定义类模板的虚函数?虚拟函数不能被内联,但为了避免在编译单元中有多个定义,它们应该被标记inline(假设模板头将包含在多个源文件中)。另一方面,编译器可以自由地忽略inline,所以这似乎是有效的。举个例子,下面的代码是否正确:

template <typename T>
class C
{
public:
    virtual void f(T val);
};

template <typename T>
inline
void C<T>::f(T val)
{
  //definition
}

?

?

BTW gcc (3.4.2) allows to omit inlinebefore definition of function f(T val)but not before analogous function of regular class. Is it only gcc's behaviour?

顺便说一句,gcc (3.4.2) 允许inline在函数定义之前省略,f(T val)但不能在常规类的类似函数之前省略。这只是gcc的行为吗?

采纳答案by jpalecek

Yes, it's OK even without inline. It works the same for ordinary member functions and static variables:

是的,即使没有也没关系inline。对于普通成员函数和静态变量,它的工作原理相同:

// everything in the header:
template <class T>
class A
{
  static int i;
};

template <class T>
int A<T>::i=0;

Standard quote: (3.2/5)

标准报价:(3.2/5)

There can be more than one de?nition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template(14.5.1.1), or template specialization for which some template parameters are not speci?ed (14.7, 14.5.5) in a program provided that each de?nition appears in a di?erent translation unit, and provided the de?nitions satisfy the following requirements ...

类类型(第 9 条)、枚举类型(7.2)、具有外部链接的内联函数(7.1.2)、类模板(第 14 条)、非静态函数模板(14.5.5)可以有多个定义。 6)、类模板的静态数据成员 (14.5.1.3)、类模板的成员函数(14.5.1.1) 或未指定某些模板参数的模板特化 (14.7, 14.5.5)程序前提是每个定义出现在不同的翻译单元中,并且这些定义满足以下要求......

The requirements basically say the two definitions have to be identical.

要求基本上说这两个定义必须相同。

It doesn't work in case of regular classes. There has to be at most one definition in the whole program.

在常规课程的情况下它不起作用。整个程序中最多只能有一个定义。

回答by Luchian Grigore

You can define template methods outside the classdefinition, in the same header, without using inlineand without receiving multiple definition errors.

您可以在定义之外的class同一个标头中定义模板方法,而无需使用inline也不会收到多个定义错误。

That's because a template function doesn't generate a definition itself, if it's not fully specialized. To prove my point, the following:

那是因为模板函数本身不会生成定义,如果它不是完全专门化的。为了证明我的观点,以下几点:

void C<int>::f(int)
{
}

will result in a linker error, as the function has a definition in this case. (provided you include this in multiple translation units. If you mark it inline:

将导致链接器错误,因为在这种情况下该函数具有定义。(前提是您将其包含在多个翻译单元中。如果您将其标记为内联:

inline void C<int>::f(int)
{
}

the error no longer occurs.

错误不再发生。

回答by Kylotan

You can define the functions there, as long as any code which needs to instantiate the function in question has visibility of that code at compile time (not link time).

您可以在那里定义函数,只要需要实例化相关函数的任何代码在编译时(而不是链接时)都可以看到该代码。

It's quite common to separate a template into 2 files, one being a traditional header, and the second being the implementation, as with non-templated functions and their implementation. The only difference is that you need to #include the template implementation file as well as the header when you want to use it.

将模板分成两个文件是很常见的,一个是传统的头文件,第二个是实现,就像非模板化函数及其实现一样。唯一的区别是您需要#include 模板实现文件以及要使用它时的标题。