this-> 是否必须从派生的 类 访问 Base<T> 标识符?
Is this-> mandatory to access Base<T> identifiers from derived classes?
此代码使用 MSVC 2015 编译,但不使用 Clang 5.0.0 (trunk 304874) 编译:
template <typename T>
struct Base
{
T data;
};
template <typename T>
struct Derived : Base<T>
{
auto getData() const
{
return data;
}
};
在 Derived::getdata()
中用 this->data
替换 data
让 Clang 高兴。
根据 C++ 标准,哪个编译器是正确的?
必须在模板代码中使用 this->
才能访问碱基的标识符 class?
是的,是的。基本上 data
取决于 T
。
有一种称为两阶段查找的机制。非(模板)相关名称会立即解析 - 在 definition 点。你的 data
还不存在,因为 Base<T>
还不存在,因为它还没有 实例化 。因此,它抱怨找不到 data
。
你需要提示编译器 data
依赖于模板,名称查找应该在第二阶段执行,在模板参数被替换之后,即模板 class 被实例化。这可以通过使用 this
或提供模板相关范围来完成。
因此,this->f()
或 Base<T>::f()
都可以。
Clang 是正确的。
.6.2/3 Dependent names [temp.dep]
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
对于return data;
,data
是不合格的,那么将采用不合格的名称查找。这意味着不应该找到基 class Base<T>
中的名称(这是一个依赖基 class 因为它依赖于模板参数 T
);即不在依赖库 classes.
中查找非依赖名称
this->data
或Base<T>::data
使其合格。这意味着将在实例化时查找名称,那时将知道必须探索的确切基础特化。
此代码使用 MSVC 2015 编译,但不使用 Clang 5.0.0 (trunk 304874) 编译:
template <typename T>
struct Base
{
T data;
};
template <typename T>
struct Derived : Base<T>
{
auto getData() const
{
return data;
}
};
在 Derived::getdata()
中用 this->data
替换 data
让 Clang 高兴。
根据 C++ 标准,哪个编译器是正确的?
必须在模板代码中使用 this->
才能访问碱基的标识符 class?
是的,是的。基本上 data
取决于 T
。
有一种称为两阶段查找的机制。非(模板)相关名称会立即解析 - 在 definition 点。你的 data
还不存在,因为 Base<T>
还不存在,因为它还没有 实例化 。因此,它抱怨找不到 data
。
你需要提示编译器 data
依赖于模板,名称查找应该在第二阶段执行,在模板参数被替换之后,即模板 class 被实例化。这可以通过使用 this
或提供模板相关范围来完成。
因此,this->f()
或 Base<T>::f()
都可以。
Clang 是正确的。
.6.2/3 Dependent names [temp.dep]
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
对于return data;
,data
是不合格的,那么将采用不合格的名称查找。这意味着不应该找到基 class Base<T>
中的名称(这是一个依赖基 class 因为它依赖于模板参数 T
);即不在依赖库 classes.
this->data
或Base<T>::data
使其合格。这意味着将在实例化时查找名称,那时将知道必须探索的确切基础特化。