Why does position of explicit template instantiation matter

萝らか妹 提交于 2021-01-27 04:45:12

问题


Say I declare a template class A in a.h

#include <iostream>

template<bool b>
class A { 
public:
  void print(std::ostream& out);
};

And define the print method in a.cpp (with explicit instatiation for true and false)

#include "a.h"

template<bool b>
void A<b>::print(std::ostream& out) {
  out << "A" << b;
}

template class A<true>;
template class A<false>;

An example main main program in main.cpp could be

#include "a.h"

int main() {
  A<true> a;
  a.print(std::cout);
}

The small project above compiles just fine.

Question: If I put the explicit instantiations above the definition of the print method (in a.cpp), the code doesn't compile anymore, with the usual undefined reference to A<true>::print(...) error.

#include "a.h"

template class A<true>;
template class A<false>;

template<bool b>
void A<b>::print(std::ostream& out) {
  out << "A" << b;
}

Why is this the case?

Edit: Makefile to compile

main : main.o a.o
    g++ main.o a.o -o main

main.o : main.cpp
    g++ -c main.cpp

a.o : a.cpp 
    g++ -c a.cpp

回答1:


I don't think there is a good natural explanation for why this is so. Clearly, the compiler could see the definition of the member function even if it is provided after the explicit instantiation – because it is located in the same file.

However, compilers are not required to this; it is in fact explicitly forbidden by the Standard:

(§14.7.2/9) An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.

I guess the reasons for this include the following:

  • There could be several distinct explicit specializations for some of the member functions later in the translation unit; it makes sense, also in the programmer's interest, to have an explicit rule about which of these will be instantiated;

  • When a template is implicitly instantiated, only specializations defined before the point of instantiation are taken into account; so the rule is the same for implicit and explicit instantiations.




回答2:


template class A<true>;
template class A<false>;

The same reason why it is typically expected that template code is defined in the header itself. To perform explicit instantiation, you (the compiler) need to be able to see the entire definition of the template class, which isn't possible from your main.cpp.

However a.cpp has access to all of the definition of the class (here the print method) so explicit instantiation works there.



来源:https://stackoverflow.com/questions/14151901/why-does-position-of-explicit-template-instantiation-matter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!