实例化点说明

Point of instantiation clarification

考虑以下代码,摘自 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)

这个我明白了,但是我不明白,当文章说的时候

The point of instantiation of a template is located immediately before the declaration that encloses its use. In this example, the point of instantiation of container is the location of the explicit instantiation

...这就是为什么当我将 void h(int) 的定义移动到 上面标记为实例化点的地方时,h(int) 仍然 不会 被调用。只有当我将它移动到 函数定义上方时才会调用它 void container<A>::member2(A).

在 VS2017 和 g++ 中就是这种情况,所以显然这篇文章措辞不当或者我遗漏了什么。有人可以澄清一下吗?

好的,上面的 link post 编辑() ultimately does answer this question, however it is not as clear as it could be. I have found this page and this page 这进一步帮助了我的理解,因此我 post 他们在这里,以便其他人可以受益。