-1

When we have a templated class (or function) that has a non-type template parameter, how are the versions generated by the compiler? Surely it doesn't create a version for every possible value of N

Suppose something like std::array<T,N> ?

I am trying to write my own templated function with a size_t template parameter, and I am trying to figure out whether/how I need to explicitly instantiate versions I will use

(I have split the program across different translation units)

I have a templated function which is something like

template <size_t N>
std::bitset<N> f(std::bitset<N> A){}

I put the declaration into a header file and definition into a .cpp file. It doesn't generate the correct version. So I tried to explicitly instantiate it like

template std::bitset<10> f<10>(std::bitset<10> A);

but I get the error that "error: explicit instantiation of .... but no definition available"

TCD
  • 151
  • 1
  • 7
  • 1
    The implementation would be included in the header & needed template instantiations would be generated on demand during compilation. – Avi Berger Jul 28 '22 at 01:43
  • 1
    That's not how template instantiation works, and there really is no answer to this question. – Stu Jul 28 '22 at 01:48
  • Definitions of function templates belong in the header file, not the `.cpp` file. Then explicit instantiations are never required. Only exception to that rule is if you are doing specific compilation time optimizations that I mentioned in my answer. But that should not apply in most situations and the standard library wouldn't apply it to types like `std::array`, only types like e.g. `std::string` (which is `std::basic_string`). – user17732522 Jul 28 '22 at 01:48

1 Answers1

2

Neither the standard library nor you need to explicitly instantiate any template specialization, whether it has non-type template parameters or not.

Any specialization of the template which is used by the user in a way that requires a definition for the specialization to exist will cause it to automatically be implicitly instantiated if a definition for the entity which is instantiated is available. The condition should normally always be fulfilled since it is standard practice to place definitions of templated entities into the header file along with their initial declaration, so that they are accessible in all translation units using them.

So std::array<T,N> will be implicitly instantiated for all pairs of types T and values N which are actually used by the translation unit.

The only situation where explicit instantiation is required is if you intent to separate the definitions of template members into a single translation unit instead of the header file where they would be available for all translation units to implicitly instantiate. But you can only do that in the first place if you know all possible values for the template parameters, and you would then need to explicitly instantiate all of them, which for most non-type template parameters is not feasible.

Aside from that explicit instantiation may be used as an optimization of compilation time by avoiding implicitly instantiating template specializations in every translation unit where they are used. That makes sense only for specializations which you know will be often used. For example some standard library implementations apply it to std::string, which is the specialization std::basic_string<char>. It doesn't really make sense to apply it to e.g. std::array.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • @DrewDormann The standard calls the entity resulting from instantiation a _specialization_, see https://www.eel.is/c++draft/temp#spec.general-4.sentence-2. Actually I do not intent to refer to the instantiation or instantiated entity though. I intent to refer to the template specialized to the specific template arguments before it is instantiated. For example you can refer to a template specialization without ever instantiating it: `using weird_string = std::basic_string;`. Not sure that the standard language is all that clear. – user17732522 Jul 28 '22 at 02:00
  • So it is... thank you for the extra info there. – Drew Dormann Jul 28 '22 at 02:13