Garmaine Staff asked 3 months ago

I'm working on a codebase which uses the following structure:

a.h:

template<int N> void f();
void b();

a.cpp:

#include "a.h"

template<> void f<1>() {}

int main()
{
    b();
}

b.cpp:

#include "a.h"
void b()
{
    f<1>();
}

The code appears to build and run correctly.

My question is: is this well-formed, or is it some kind of ill-formed NDR that happens to work?


If building with clang -Wundefined-func-template (this was enabled in my IDE's default settings for clang-tidy) then a warning is produced:

b.cpp:5:2: warning: instantiation of function 'f<1>' required here, but no definition is available [-Wundefined-func-template]
        f<1>();
        ^
./a.h:1:22: note: forward declaration of template entity is here
template<int N> void f();
                     ^
b.cpp:5:2: note: add an explicit instantiation declaration to suppress this warning if 'f<1>' is explicitly instantiated in another translation unit
        f<1>();
        ^

But I am not sure whether to just disable the warning, or make some code change (other than moving the explicit specialization definition to the header file, which would not be preferable for this project).

Following the advice in the warning message and adding an explicit instantiation declaration to the header file (i.e. extern template void f<1>();) caused an error message (implicit instantiation of a specialization before explicit instantiation).

However, adding an explicit specialization declaration template<> void f<1>(); to the header file suppresses the warning. But I am not sure if this is (a) necessary, and/or (b) recommended style.