I recently [got to know](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2138) that the following code is ill-formed, NDR:

```cpp
// 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:

```cpp
// 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?