Соответствует ли `member_variable.a_type::b_type::static_function()` стандарту C++?

В проекте, расширяющем библиотеку boost.intrusive, который я недавно рассмотрел, я обнаружил в классе следующий код treap_impl:

node_ptr this_head(this->tree_type::header_ptr());
node_ptr right(this->tree_type::node_algorithms::root_node(this_head));

Рассматриваемый код компилируется в MSVC 17.9, но не использует clang или gcc из-за ошибки во второй строке:

...::node_algorithms is not a base of treap_impl<...>

Удаление this-> из второй строки устраняет ошибку.

Мои вопросы:

  1. Соответствует ли этот код, особенно часть this->tree_type, стандарту C++?
  2. Какой раздел стандарта C++ здесь уместен?
  3. Есть ли какие-то базовые знания C++, которые я здесь упускаю из виду?

Вот пример, который воспроизводит одну и ту же ошибку в gcc и clang. Это также не удается скомпилировать с MSVC в проводнике компилятора. К сожалению, я не уверен, как воспроизвести точную настройку, описанную выше, то есть, что необходимо для компиляции с MSVC, но не с gcc/clang.

struct static_thing {
  static int value() {
    return 5;
  }
};

struct A {
  using the_type = static_thing;
};

class B {
  using a_type = A;

  void do_stuff() {
    int a(this->a_type::the_type::value());
  }
};

Рассматриваемая ошибка:

error: ‘A::the_type’ {aka ‘static_thing’} is not a base of ‘B’

Когда вы сказали this->tree_type::node_algorithms::root_node(this_head), вы пытались сказать «вызвать root_node(this_head) из пространства имен tree_type::node_algorithms»? Если да, то это не метод, а отдельная функция. Вы можете вызывать методы без явного this->, но не можете вызывать функции как метод. Методы принадлежат объекту и нуждаются в объекте в качестве контекста, функции являются автономными и не имеют контекста.

Ext3h 05.08.2024 12:14

«К сожалению, я не уверен, как точно воспроизвести описанную выше настройку». Вы можете добавить библиотеку boost и включить необходимые заголовки даже в Compiler Explorer.

Ted Lyngmo 05.08.2024 12:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

this->a_type::the_type::value() говорит: «Найдите метод или вызываемый член с именем value в базовом классе a_type::the_type и вызовите его». Его можно вызывать как вызываемый объект, как метод со скрытым аргументом this или как метод static, но в любом случае для поиска доступны только члены и методы-члены.

В отличие от одного a_type::the_type::value(), который в этом контексте также мог означать то же самое, но также имел другую перегрузку: «найти функцию или вызываемую переменную с именем value в пространстве имен a_type::the_type и вызвать ее без аргументов». Список членов базового класса по-прежнему имеет приоритет в качестве пространства имен для поиска, но вы больше не ограничены только базовыми классами.

Что касается того, что понял/хотел компилятор:

struct static_thing {
  static int value() {
    return 5;
  }
};

struct A {
  using the_type = static_thing;
};

// There is now value() from static_thing as a member on B
// static_thing is additionally known by the alias a_type::the_type
class B : public static_thing {
  using a_type = A;

  void do_stuff() {
    int a(this->a_type::the_type::value());
  }
};

Применительно к вашему исходному вопросу класс treap_impl должен был унаследовать от класса node_algorithms, чтобы получить доступ к признакам, определенным в этом классе.

Другие вопросы по теме