Template specialization in .cpp file + primary template declaration in .h file

Viewed 415

According to https://eel.is/c++draft/temp.expl.spec#7:

If a template, a member template or a member of a class template is explicitly specialized, a declaration of that specialization shall be reachable from every use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

Therefore I wonder, is the following program ill-formed, NDR?

// foo.h
template <typename T>
void foo();

// Specialization not declared in the header!

// foo.cpp
#include "foo.h"

template <>
void foo<int>()
{
 // ...
}

// main.cpp
#include "foo.h"

int main()
{
    foo<int>();
}
2 Answers

Looks like this exact case is covered in the standards committee's "Closed Issues List", which you can read here, very hard to get more authoritative than that.

TL;DR:

Rationale (March, 2016):

As stated in the analysis, the intent is for the example to be ill-> formed, no diagnostic required.

Note that you can find quite a few SO questions that are pretty similar to this. I found this one for example, in which one answerer cites the working group discussion.

Therefore I wonder, is the following program ill-formed, NDR?

It is. This is main.cpp after all the pre-processing:

template <class> void foo(); // forward declaration of templated entity

int main() {
  foo<int>(); // Implicit instantiation: Ill Formed; No diagnosis required.
}

You might get a linker error like: undefined reference to 'void foo<int>()'.
You might not get an error (pre-compiled header, dynamic library...)

Why is diagnosing not required?
Phase 4: Preprocessing (the code above is formed during this phase)
Phase 7: Compilation (producing translation units)
Phase 8: Template instantiation occurs
Phase 9: The last one. This is when the function definition is found (or not) and linked to the executable

See: Translation Phases

Related