Каково правило, позволяющее `this->` обращаться к членам зависимых базовых классов?

Как известно, приведенный ниже код плохо сформирован, поскольку член x находится в зависимом базовом классе. Однако изменение x до this->x на указанной строке устранит ошибку.

template <typename T>
struct B {
    int x;
};
template <typename T>
struct C : B<T> {
    void f() {
        int y = x; // Error!
    }
};
int main() {
    C<int> c;
    c.f();
}

Я хотел бы объяснить, как это поведение указано в стандарте. Согласно [temp.dep]/3:

В определении шаблона класса или класса, если базовый класс зависит от шаблона-параметра, базовый класс область не рассматривается при поиске неквалифицированного имени либо в точке определения шаблона класса или член или во время создания шаблона или члена класса.

Похоже, что это объясняет, почему использование x в одиночку терпит неудачу. Имя x просматривается в точке определения, а область базового класса не рассматривается. Однако, что, если мы используем this->x? Теперь имя x зависит и его поиск откладывается до экземпляра. Но цитируемый параграф, по-видимому, подразумевает, что x не может быть найден даже во время создания экземпляра, так как поиск x в this->x по-прежнему неквалифицированный поиск.

Очевидно, что реализации не ведут себя таким образом, и он широко понимал, что область базового класса просматривается после создания экземпляра шаблона.

  • Я неверно истолковал цитируемый параграф?
  • Есть ли абзац, который указывает "правильное" поведение?

Ответы

Ответ 1

Выражения доступа к членам класса (5.2.5. [expr.ref]) не используют неквалифицированные правила поиска, они используют правила поиска доступа к членам класса (3.4.5 [basic.lookup.classref]).

(2) Если id-выражение в доступе члена класса (5.2.5) является неквалифицированным-id, а тип выражения объекта имеет тип класса C, неквалифицированный идентификатор просматривается в области класса C.