为什么来自非依赖基 类 的非限定名称优于模板参数

Why are unqualified names from nondependent base classes favored over template parameters

C++ 标准规定来自非依赖基 类 的非限定名称优先于模板参数。这背后的原因是什么?

以下代码段来自 C++ 模板:

#include <iostream>

template <typename X>
class Base {
    public:
        int basefield;
        using T = int;
};

class D1 : public Base<Base<void>> {
    public:
        void f() { basefield = 3; // works as normal 
        }
};

template <typename T>
class D2 : public Base<double> {
    public:
        void f() { basefield = 7; }
        T strange;  // what type am I ???
};

int main() {
    D2<std::string> d;
    d.strange = 100;
}

// what type am I ???

当在模板推导中查找不合格的名称时(如D2),在模板参数列表之前考虑非依赖碱基。

在您的例子中,这意味着 class 模板 D2 的成员 strange 始终具有对应于 Base<double>::T 的类型 T(这只不过是 int).

您可以通过将 d.strange = 100; 更改为:

来确认这一点
d.strange = "100"; //this will give error saying: invalid conversion from ‘const char*’ to ‘Base::T’ {aka ‘int’}

以上语句产生错误:

invalid conversion from ‘const char*’ to ‘Base::T’ {又名 ‘int’} 这确认 strange 具有类型 int.


What is the reasoning behind this?

标准这么说的一个原因可能是因为当开始查找名称时,它会从遇到名称的位置向上(向上)。现在,在向上搜索名称时,首先遇到 non-dependent Base,因此名称被解析为属于 non-dependent Base(显然 Base 必须有一个名称相同的成员正在查找)。也就是说,因为在这种情况下 Base 独立于模板参数并且因为它在查找发生时首先出现(从名称声明的点到向上的方向),所以 non-dependent基础优先。

另一方面,在依赖 Base 的情况下,必须首先知道模板参数才能知道依赖 Base。也就是说,在这种情况下,Base 并不独立于模板参数。因此,当查找发生时(再次向上方向),即使在模板参数之前遇到依赖 Base,依赖 Base 在知道模板参数之前是未知的。所以在这种情况下,模板参数优先是有意义的。

这是我目前对标准如此规定的推理。

不合格查找大致等同于在每个包含范围内尝试 合格 查找并保持第一个命中。由于 D2<…>::T 可以找到 Base<double>::T,因此在 class 的范围内查找成功;对于词法引入的模板参数,该查找自然先于 outside the class.

此首选项还可避免在

之间进行不合格的名称更改
template<class T>
struct A : B {
  Z z;
  void f();
  // …
};

template<class Z>
void A<Z>::f() {
  Z z;
  // …
}

尽管 namespace-scope 名称仍然可以进行相同的更改。

就是说,即使是委员会也已经 divided 遵守这一特定规则,因为更喜欢一个你在 base class 中看不到的名字而不是你在template-head.