模板类的实例化点

use*_*538 7 c++ templates instantiation token-name-resolution c++14

该代码可以编译吗?

#include <iostream>

template <typename T>
struct TMPL
{
    using TP = typename T::TP; //is CL::TP visible (with T == CL)?
};

struct CL
{
    using TP = int;
    TMPL<CL>::TP val; 
};

int main()
{
    CL cl;
}
Run Code Online (Sandbox Code Playgroud)

根据标准14.6.4.1/4,在CL类定义之前立即实例化TMPL

对于类模板专业化,...,如果专业化隐式实例化,因为它是从另一个模板特内引用,...... 否则,实例化的这样一个专业化的点后面紧跟的命名空间范围声明或定义,是指专业化.

因此,CL :: TP在TMPL实例化点中不可见,但所有编译器(MSVC,gcc,clang)都编译得很好.我还发现了一份缺陷报告http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287,但显然未被接受

uh *_*per 2

您的示例与缺陷报告中的示例不同。在缺陷报告中,CL是一个类模板。然而,拟议决议的目的是使模板案例与非模板案例相同,又名[basic.scope.pdecl]

\n\n
\n

6 在类成员声明点之后,可以在其类的范围内查找成员名称。[注意:即使该类是不完整的类,这也是正确的\n。例如,

\n\n
struct X {\n  enum E { z = 16 };\n  int b[X::z];      // OK\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94尾注]

\n
\n\n

然后提出决议:

\n\n
\n

在 14.6.4.1 [temp.point] 第 3 段中更改:

\n\n

实例化点紧邻封闭模板的实例化点之前。否则,此类专门化的实例化点紧邻引用该专门化的命名空间作用域声明或定义之前。

\n\n

到:

\n\n

实例化点与封闭模板的实例化点相同否则,此类专门化的实例化点紧邻 最近的封闭声明之前。[注意:实例化点仍在命名空间范围内,但实例化点之前的任何声明,即使不在命名空间范围内,也被视为已被看到。]

\n\n

增加以下第3段:

\n\n

如果隐式实例化的类模板特化、类成员特化或类模板特化引用了包含直接特化引用的类、类模板特化、类成员特化或类模板特化,\n或间接导致实例化,则在专门化引用的上下文中应用类引用的完整性和排序要求。

\n
\n\n

截至最新草案,非模板案例过去和现在仍然有效。模板案例则不然。然而,缺陷在于起草,这意味着模板案例旨在编译。

\n\n
\n

起草:工作组已达成非正式共识,并在暂定决议中进行了粗略的描述,但尚未提供变更的精确措辞。

\n
\n