【发布时间】:2018-05-07 11:57:14
【问题描述】:
a.hpp:
#pragma once
struct S
{
static int v;
};
int S::v = 0;
b.hpp:
#pragma once
void addOne();
b.cpp:
#include "b.hpp"
#include "a.hpp"
void addOne()
{
S::v += 1;
}
main.cpp:
#include <iostream>
#include "a.hpp"
#include "b.hpp"
int main()
{
S::v = 2;
addOne();
S::v += 2;
std::cout << S::v << std::endl;
}
使用g++ -std=c++14 main.cpp b.cpp && ./a.out(S::v 的多重定义)编译时不起作用。
但是,当我将代码更改为: a.hpp:
#pragma once
struct S
{
template<typename T>
static int v;
};
template<typename T>
int S::v = 0;
并将所有 S::v 替换为 S::v<void> 它编译并按照我希望第一个示例工作的方式工作(输出 5)。
我相信我知道为什么第一个代码示例不起作用:int S::v = 0; 行在main.cpp 单元中编译一次,在b.cpp 单元中编译一次。当链接器将这两者链接在一起时,变量S::v 基本上会被重新定义。(?)
为什么带有模板的代码可以工作?
【问题讨论】:
-
您可以尝试将
int S::v = 0;移动到a.cpp看看会发生什么 -
如果 struct 是模板,这甚至可以在 c++14 之前工作。它只是静态模板变量(和模板方法)的一个属性——允许在不同的翻译单元中进行多个定义。
-
如果您有 C++17,请在其中粘贴
inline。
标签: c++ templates compilation c++14