【问题标题】:Template instance in different translation units [duplicate]不同翻译单元中的模板实例[重复]
【发布时间】:2015-06-04 17:11:33
【问题描述】:

据我所知,每个模板在每个翻译单元上都有不同的实例,据我了解,翻译单元大致是一个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.cppb.cpp 都使用int 模板的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。

那么问题是什么?

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

【问题讨论】:

    标签: c++ templates translation-unit


    【解决方案1】:

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

    是的。错了。
    每个类型不是每个翻译单元创建模板函数的副本。

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

    【讨论】:

    • 您介意在标准中提到这个特性吗?
    • @PaperBirdMaster 看到建议重复的问题。
    • @Suma 感谢:标准 3.2/5 单一定义规则。可以阅读here
    • 每个类型不是每个翻译单元创建模板函数的副本似乎也发生在C++14 变量模板(见Wandbox),不是吗?
    • @PaperBirdMaster,是的,没错。由于它是模板化的,无论如何它只会有 1 个副本。但是,如果您对其进行专门化,则会再次导致多重定义错误。例如template&lt;typename T&gt; T a = 1; template&lt;&gt; int a = 0;,如果你把这条语句放在一个公共头文件中,那么第二条语句将导致链接器错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多