c++functiontemplates

explicit template function instantiation - Howto find the codepoints where it's been used?


I like to know how I can find the codepoints where an explicit instantiated template function is been used.

template <typename T> RNNullableTyped<T> Get(const json::json &json);
template <> RNNullableTyped<int         > Get(const json::json &json);
template <> RNNullableTyped<double      > Get(const json::json &json);
template <> RNNullableTyped<std::string > Get(const json::json &json);
template <> RNNullableTyped<std::wstring> Get(const json::json &json);

std::string AsString(const json::json &elem)
{
  return Get< std::string >(elem).Get();
}

Now I like to find codepoints like the above, but I cannot easily search for it. If I comment it out, I just get an unresolved external linker error. Annotate it as deprecated seems not to be supported for template functions.

So, to solve that issue a colleague of mine is going to replace those temple function with explicit once like GetInt, GetDouble, GetStdString, GetStdWstring ... and so forth, which I do not like very much....

What I hope for is that someone can show me a way how to find the points in code where a explicit instantiated template function is been used.

I should add, that we use the Microsoft Visual C++ compiler.

Regards, Ronald.


Solution

  • First of all, these are explicit specialization declarations, not explicit instantiation definitions. Explicit specialization declarations begin with template<>, while explicit instantiation declarations begin with template or extern template, neither followed by <.

    For the explicit specialization declarations there must be corresponding explicit specialization definitions somewhere in a source file.

    You can find all uses of the specialization either via tools of your IDE (ideally it should be able to show you all references to a specific specialization of the function template.)

    Alternatively you can mark the explicit specializations with [[deprecated]] which should cause the compiler to emit a warning when they are referred to:

    template <> [[deprecated]] RNNullableTyped<int         > Get(const json::json &json);
    

    Alternatively you can mark the explicit specialization declaration as inline in the header file, but then comment out the explicit specialization definition in the source file. Then, hopefully, the compiler should warn when the explicit specialization is odr-used because its definition is not available although it is marked inline:

    template <> inline RNNullableTyped<int         > Get(const json::json &json);
    

    Another possibility would be to define the explicit specilizations as deleted:

    template <> RNNullableTyped<int         > Get(const json::json &json) = delete;
    

    Then the compiler will fail to compile any use of the specialization.