I was reading about explicit template instantiation when i came across the following answer:
Assuming by "explicit template instantiation" you mean something like
template class Foo<int>; // explicit type instantiation // or template void Foo<int>(); // explicit function instantiation
then these must go in source files as they considered definitions and are consequently subject to the ODR.
My question is that is the above claim that explicit template instantiation definition cannot be put into header files(and must be put into source files) technically correct. I am looking for an exact reference from the standard(or equivalent source) where it is specified that these ETI definitions cannot be put into header files.
I also tried this in a sample program which compiles and links fine without giving any multiple definition error(demo) in both gcc and clang even though i have put the ETIs into the header. Is the below given program well-formed according to the standard?
Header.h
#ifndef MYHEADER_H
#define MYHEADER_H
#include <string>
template<class T>
int func( const T& str)
{
return 4;
}
template int func<std::string>( const std::string& str); //first ETI in header. Will the program be well formed if this header is included in multiple source files?
template int func<double>(const double& d); //second ETI in header
#endif
source2.cpp
#include "Header.h"
source3.cpp
#include "Header.h"
main.cpp
#include <iostream>
#include "Header.h"
int main(){
std::string input = "123";
auto result = func(input);
std::cout<<result<<std::endl;
}
CodePudding user response:
From explicit instantiation's documentation:
An explicit instantiation definition forces instantiation of the class, struct, or union they refer to. It may appear in the program anywhere after the template definition, and for a given argument-list, is only allowed to appear once in the entire program, no diagnostic required.
(emphasis mine)
This means that the shown program in question is in violation of the above quoted statement and thus ill-formed no diagnostic required.
The same can be found in temp.spec:
For a given template and a given set of template-arguments,
- an explicit instantiation definition shall appear at most once in a program
An implementation is not required to diagnose a violation of this rule.
(emphasis mine)
This again leads to the conclusion that the given example program is ill-formed NDR.
CodePudding user response:
Technically, it's fine to have an explicit instantiation in a header - so long as that header is only included once.
It's more accurate to say it can only occur once per program (which is why the standard does exactly that).
Practically this is almost a distinction without a difference, as there's not much point writing such a header in the first place.