3

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

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

// test.hpp
template <typename T> void test()
{
    static T t = T(0);
    return t++;
}

对于每个翻译单元,test即使每个翻译单元的模板参数T相同,我也应该有一个不同的实例。我决定对其进行测试,因此我创建了以下文件(为简洁起见,省略了包括守卫):

// a.hpp
namespace A { void f(); }

// a.cpp
#include <iostream>
#include "a.hpp"
#include "test.hpp"
namespace A
{
void f() { std::cout << test<int>(); }
}

// b.hpp
namespace B { void f(); }

// b.cpp
#include <iostream>
#include "b.hpp"
#include "test.hpp"
namespace B
{
void f() { std::cout << test<int>(); }
}

我们可以看到,两者都a.cpp使用b.cpp了模板的int实例,test()但是在不同的翻译单元中,所以执行下面的程序:

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

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

我期待一个输出,00但我得到01了。我用来测试此代码的 IDE 是 MSVC2010 V10.0.4 SP1。

那么问题是什么?

  • 我对模板和翻译单元的理解有误吗?或者...
  • 我对这个测试代码做错了什么?
4

1 回答 1

1

我对模板和翻译单元的理解有误吗?

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

在您的情况下,test<int>仅创建 1 个副本,并且在所有 TU 中使用相同的副本。

于 2015-03-31T11:24:02.267 回答