I recently got to know that the following code is ill-formed, NDR:
// foo.h
template <typename T>
void foo();
// foo_bar.cpp
template <>
void foo<bar>()
{ /* Implementation for bar */ }
// foo_baz.cpp
template <>
void foo<baz>()
{ /* Implementation for baz */ }
Due to the specializations not being declared in foo.h
. The reason for not declaring them in foo.h
is to avoid #include
'ing the definitions of baz
and bar
(long build times).
Explicit instantiations do not suffer from this problem - there's no need to declare them in the header. Therefore I thought about solving the above problem using explicit instantiation instead:
// foo.h
template <typename T>
void foo();
// foo_bar.cpp
template <typename T>
void foo()
{ /* Implementation for bar */ }
template void foo<bar>();
// foo_baz.cpp
template <typename T>
void foo()
{ /* Implementation for baz */ }
template void foo<baz>();
In some way, it would be replacing specializations with explicit instantiations. But then comes my question: is having two different implementations of the primary template foo<T>
violating ODR, assuming they are instantiated for different types?