Mr.*_*C64 26 c++ inheritance templates language-lawyer name-lookup
此代码使用MSVC 2015进行编译,但不使用Clang 5.0.0(主干304874)进行编译:
template <typename T>
struct Base
{
T data;
};
template <typename T>
struct Derived : Base<T>
{
auto getData() const
{
return data;
}
};
Run Code Online (Sandbox Code Playgroud)
data用this->datain 替换Derived::getdata()让Clang高兴.
根据C++标准,哪个编译器是正确的?
必须this->在模板代码中使用才能访问基类的标识符?
son*_*yao 27
铿锵是对的.
在类或类模板的定义中,在类模板或成员的定义点或类模板或成员的实例化期间,在非限定名称查找期间不检查从属基类的范围.
对于return data;,data是不合格的,那么不合格的名称查找会被采用.这意味着不应该找到基类中的名称Base<T>(因为它取决于模板参数,它是依赖基类T); 即,非依赖名称不会在依赖基类中查找.
this->data或Base<T>::data使其合格.这意味着将在实例化时查找名称,并且在那时必须知道必须探索的确切基本特化.
luk*_*k32 15
是的.基本上data取决于T.
有一种称为两阶段查找的机制.非(模板)相关名称会立即解析 - 在定义时.你data还不存在,因为Base<T>它还没有实例化,因为它还没有实例化.因此,它抱怨data没有找到.
您需要提示data依赖于模板的编译器,并且在替换模板参数后,应在第二阶段执行名称查找,即模板类已实例化.这可以通过使用this或提供依赖于模板的范围来完成.
所以,要么this->f()或Base<T>::f()将要工作.