class 模板被实例化时,成员模板声明是否也被实例化?

When a class template is instantiated, is a member template declaration also instantiated?

让我们举个例子:

template<typename T> struct foo
{
    template<typename X> void bar(void (T::*)()) {}
    template<typename X> void bar(X*) {}
    template<typename X> void bar(T**) {}
};

int main() { foo<int> p; }

上面class foo<int>的实例化会实例化成员模板声明bar即使成员本身是模板吗?任何来自标准的参考将不胜感激。

答案是肯定的。

引用自 C++11 标准,[temp.inst] [14.7.1]:

  1. ...
    The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or exception-specifications of the class member functions, member classes, scoped member enumerations, static data members and member templates; and it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.

第二部分有更多关于成员模板定义实例化的确切时间的信息。 (它通常隐式发生,当它们被使用时:)

  1. Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.