Dar*_*ieb 6 c++ templates compilation c++14
a.hpp:
#pragma once
struct S
{
static int v;
};
int S::v = 0;
Run Code Online (Sandbox Code Playgroud)
b.hpp:
#pragma once
void addOne();
Run Code Online (Sandbox Code Playgroud)
b.cpp:
#include "b.hpp"
#include "a.hpp"
void addOne()
{
S::v += 1;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
使用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;
Run Code Online (Sandbox Code Playgroud)
并S::v用S::v<void>它来替换所有编译并运行我想要的第一个例子工作(输出5).
我相信我知道为什么第一个代码示例不起作用:该int S::v = 0;行在main.cpp单元中编译一次,在b.cpp单元中编译一次.当链接器将这两者链接在一起时,变量S::v基本上被重新定义.(?)
为什么带模板的代码有效?
为什么带有模板的代码可以工作?
本质上,因为标准是这么说的。
对于模板,规则通常相当于:“使用它们的每个人都必须有可用的定义。” 这同样适用于类模板的静态数据成员:此类静态数据成员的定义必须存在于使用 odr 的每个翻译单元中。由编译器和链接器来确保这不会导致错误。
请注意,从 C++17 开始,您可以通过使静态数据成员内联来解决非模板情况:
#pragma once
struct S
{
static inline int v = 0;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |