c++functiontemplatesspecialization

C++ template function specialization error when specialization is in different header


In cnvt.h header there is:

template <typename t_to, typename t_from> std::optional<t_to> cnvt(t_from);

And in header int.h, we have:

#include "cnvt.h" 

template <>
std::optional<uint8_t> cnvt<uint8_t, const char *>(const char *) {
  // actual code replaced for simplicity
  return {};
}

As it is, clang-tidy reports

clang reports "int.h:: Included header cvnt.h is not used directly (fix available) Included header cvnt.h is not used directly (fix available)

And if remove #include "cnvt.h", it reports

int.h:9:24: No function template matches function template specialization 'cnvt'

I searched StackOverflow, and the posts about function template specialization did not help.


Solution

  • This warning comes from clangd rather than clang-tidy. For the code you have written, you do need the cnvt.h header included. clangd just doesn't see that you require the primary template from that header for the specialization.

    From the clangd documentation:

    I’m using a symbol in a tricky way (e.g. through a template), but the header is marked as unused

    There are some types of uses the analysis cannot find.

    Suppress the warning with // IWYU pragma: keep

    So you should be able to suppress the warning by adding // IWYU pragma: keep after the include for cnvt.h.

    However, if you can I'd recommend side-stepping the problem entirely and using function overloading instead of template specialization:

    std::optional<uint8_t> cnvt(const char *) {
      // actual code replaced for simplicity
      return {};
    }
    

    This removes the need for the primary template to be visible in your int.h header.