模板函数内的静态变量 [英] Static variable inside template function

查看:144
本文介绍了模板函数内的静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,如果您在header.hpp中定义此函数

In C++, if you define this function in header.hpp

void incAndShow()
{
  static int myStaticVar = 0;
  std::cout << ++myStaticVar << " " << std::endl;
}

并且至少包含两个.cpp文件中的header.hpp。然后你将有多重定义incAndShow()。这是预期。但是,如果您向函数

and you include header.hpp in at least two .cpp files. Then you will have multiple definition of incAndShow(). Which is expected. However, if you add a template to the function

template <class T>
void incAndShow()
{
  static int myStaticVar = 0;
  std::cout << ++myStaticVar << " " << std::endl;
}

那么你不会有任何 错误。同样,两个不同的.cpp调用具有相同模板的函数(例如 incAndShow< int>()),将共享 myStaticVar 。这是正常吗?我问这个问题,因为我确实依赖于这个特性(共享静态变量),我想确保这不仅是我的实现是这样做的。

then you won't have any multiple definition of error. Likewise, two different .cpp calling the function with the same template (e.g. incAndShow<int>()), will share myStaticVar. Is this normal? I'm asking this question, because I do rely on this "feature" (sharing the static variable) and I want to be sure that it is not only my implementation that is doing this.

推荐答案

你可以依赖这个。 ODR(一个定义规则)在标准中的 3.2 / 5 处表示,其中 D 代表非静态函数模板(我的cursive字体)

You can rely on this. The ODR (One Definition Rule) says at 3.2/5 in the Standard, where D stands for the non-static function template (cursive font by me)


如果D是一个模板,并且在多个翻译单元中定义,上述列表中的要求应适用于模板定义(14.6.3)中使用的模板包围范围中的名称,以及实例化点(14.6.2)处的依赖名称。如果D的定义满足所有这些要求,则程序将表现得像D的单个定义那样。如果D的定义不满足这些要求,则行为是未定义的。

在最近四个要求中,两个最重要的是大致

Of the last four requirements, the two most important are roughly


  • 每个定义中的每个定义应由相同的标记序列组成

  • 每个定义中的名称应指代相同的事物(实体)

编辑

我认为这不足以保证你的静态变量在不同的实例化都是一样的。以上仅保证模板的多个定义有效。它不会说出从它产生的专业化。

I figure that this alone is not sufficient to guarantee that your static variables in the different instantiations are all the same. The above only guarantees that the multiple definitions of the template is valid. It doesn't say something about the specializations generated from it.

这是链接所在的位置。如果函数模板专用化的名称$ c> 3.5 / 4 ),那么引用这种特殊化的名称指的是相同的函数。对于声明为静态的模板,由于

This is where linkage kicks in. If the name of a function template specialization (which is a function) has external linkage (3.5/4), then a name that refers to such a specialization refers to the same function. For a template that was declared static, functions instantiated from it have internal linkage, because of


从内部链接实例化的实体具有内部链接从其他翻译单位生成的所有实体。 - 14/4

具有命名空间范围(3.3.6)的名称具有内部链接名称[...]明确声明的对象,引用,函数或函数模板static - 3.5 / 3

A name having namespace scope (3.3.6) has internal linkage if it is the name of [...] an object, reference, function or function template that is explicitly declared static -- 3.5/3

如果函数模板没有用static声明,那么它有extern链接(顺便说一下,也是我们必须遵循ODR的原因。 , D 不会被多重定义!)。这可以从 14/4 (与 3.5 / 3 )一起导出

If the function template wasn't declared with static, then it has extern linkage (that, by the way, is also the reason that we have to follow the ODR at all. Otherwise, D would not be multiply defined at all!). This can be derived from 14/4 (together with 3.5/3)


非成员函数模板可以具有内部链接;任何其他模板名称应具有外部链接。 - 14/4

最后,我们得出结论,从具有外部链接的函数模板生成的函数模板专用化本身具有 3.5 / 4

Finally, we come to the conclusion that a function template specialization generated from a function template with external linkage has itself external linkage by 3.5/4:


具有命名空间范围的名称具有外部链接[...]一个函数,除非它有内部链接 - 3.5 / 4

对于由显式专门化提供的函数, 3.5 / 3 解释了它具有内部链接,而 14/4 用于生成的特殊化(模板实例化)。由于您的模板名称有外部链接,所有的专业都有外部链接:如果你使用他们的名字( incAndShow< T> )从不同的翻译单位,函数,这意味着你的静态对象将是相同的在每一个场合。

And when it has internal linkage was explained by 3.5/3 for functions provided by explicit specializations, and 14/4 for generated specializations (template instantiations). Since your template name has external linkage, all your specializations have external linkage: If you use their name (incAndShow<T>) from different translation units, they will refer to the same functions, which means your static objects will be the same in each occasion.

这篇关于模板函数内的静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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