Рассмотрим следующий код, взятый из https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/name_binding.htm:
#include <iostream>
using namespace std;
void f(double) { cout << "Function f(double)" << endl; }
template <class A> struct container{ // point of definition of container
void member1(){
// This call is not template dependent,
// because it does not make any use of a template parameter.
// The name is resolved at the point of definition, so f(int) is not visible.
f(1);
}
void member2(A arg);
};
void f(int) { cout << "Function f(int)" << endl; }
void h(double) { cout << "Function h(double)" << endl; }
template <class A> void container<A>::member2(A arg){
// This call is template dependent, so qualified name lookup only finds
// names visible at the point of instantiation.
::h(arg);
}
template struct container<int>; // point of instantiation of container<int>
void h(int) { cout << "Function h(int)" << endl; }
int main(void){
container<int> test;
test.member1();
test.member2(10);
return 0;
}
Вывод:
Function f(double)
Function h(double)
Я понимаю это, но чего я не понимаю, когда в статье говорится
Точка создания шаблона находится непосредственно перед объявлением, которое включает его использование.В этом примере точка создания контейнера - это местоположение явной реализации
... поэтому, когда я перемещаю определение void h(int)
выше , то, что помеченов качестве точки инстанции, h(int)
все еще не вызывается .Он вызывается только когда я перемещаю его выше определения функции void container<A>::member2(A)
.
Это имеет место в VS2017 и g ++, поэтому ясно, что статья написана плохо или ячего-то не хватаетМожет кто-нибудь уточнить, пожалуйста?