Let's consider some synthetic but expressive example. Suppose we have Header.h:
Header1.h
#include <iostream>
// Define generic version
template<typename T>
inline void Foo()
{
std::cout << "Generic
";
}
Header2.h
void Function1();
Header3.h
void Function2();
Source1.cpp
#include "Header1.h"
#include "Header3.h"
// Define specialization 1
template<>
inline void Foo<int>()
{
std::cout << "Specialization 1
";
}
void Function1()
{
Foo<int>();
}
Later I or some else defines similar conversion in another source file.
Source2.cpp
#include "Header1.h"
// Define specialization 2
template<>
inline void Foo<int>()
{
std::cout << "Specialization 2
";
}
void Function2()
{
Foo<int>();
}
main.cpp
#include "Header2.h"
#include "Header3.h"
int main()
{
Function1();
Function2();
}
The question is what will print Function1() and Function2()? The answer is undefined behavior.
I expect to see in output:
Specialization 1
Specialization 2
But I see:
Specialization 2
Specialization 2
Why C++ compilers are silent about ODR violation? I would prefer compilation to be failed in this case.
I found only one workaround: define template functions in unnamed namespace.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…