C++ 不同翻译单元中的模板实例

C++ 不同翻译单元中的模板实例,c++,templates,translation-unit,C++,Templates,Translation Unit,据我所知,每个模板在每个翻译单元上都有不同的实例,据我所知,翻译单元大致是一个cpp文件 因此,如果我有一个名为test.hpp的文件,其中包含以下内容: // test.hpp template <typename T> void test() { static T t = T(0); return t++; } 如我们所见,a.cpp和b.cpp都使用test()模板的int实例,但使用不同的翻译单元,因此执行以下程序: // main.cpp #include

据我所知,每个模板在每个翻译单元上都有不同的实例,据我所知,翻译单元大致是一个
cpp
文件

因此,如果我有一个名为
test.hpp
的文件,其中包含以下内容:

// test.hpp
template <typename T> void test()
{
    static T t = T(0);
    return t++;
}
如我们所见,
a.cpp
b.cpp
都使用
test()
模板的
int
实例,但使用不同的翻译单元,因此执行以下程序:

// main.cpp
#include "a.hpp"
#include "b.hpp"

int main()
{
    A::f();
    B::f();
    return 0;
}
我本来希望输出
00
,但结果却是
01
。我用来测试这段代码的IDE是MSVC2010 V10.0.4 SP1

那么问题是什么

  • 我对模板和翻译单位的理解是否错误?或者
  • 我的测试代码有问题吗
我对模板和翻译单位的理解是否错误

对。这是错误的。
模板函数的副本是按类型创建的,而不是按翻译单元创建的


在您的情况下,对于
测试
只创建了一个副本,并且在所有TU中都使用了相同的副本。

您是否介意提及标准中提到的这一特征在哪里?@PaperBirdMaster请将建议的问题视为重复。@Suma感谢:标准3.2/5一个定义规则。它可以读取。模板函数的副本是按类型创建的,而不是按翻译单元创建的。似乎C++14变量模板也会这样(参见中),不是吗?@PaperBirdMaster,是的,这是正确的。因为它是模板化的,所以无论如何它只有一个副本。但是,如果您专门化它,那么它将再次导致多个定义错误。e、 g.
模板T a=1;模板int a=0,如果将此语句放入公共头文件中,则第二条语句将导致链接器错误。
// main.cpp
#include "a.hpp"
#include "b.hpp"

int main()
{
    A::f();
    B::f();
    return 0;
}