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
по существу переопределяется. (?)
Почему работает код с шаблоном?