Почему частное наследование не разрешает неоднозначность для статических функций? (проверено в MSVC)

Мне интересно, почему вызов статической функции неоднозначен, даже если одно из двух явным образом невозможно вызвать, поскольку оно является частным.
Я надеялся, что смогу использовать частное / защищенное наследование, чтобы помочь компилятору решить эту неоднозначность.

Это специфично для MSVC или как-то указано в стандарте?

struct A
{
static int num() { return 0; }
};

struct B
{
static int num() { return 1; }
};

struct C : public A, private B
{};

int main()
{
C::num(); // Ambiguous access of num
}

Предпосылкой является то, что я пытался использовать способ перегрузки (тот, что в A) во многих производных классах (C, D, E, F, G), наследуя его, чтобы каким-то образом придерживаться правила «Не повторять». Сам.

5

Решение

Да, это указано в стандарте C ++, раздел §3.4 [basic.lookup]

Правила доступа (пункт 11) рассматриваются только после успешного поиска имени и разрешения перегрузки функции (если применимо)

Поиск имени не заботит о доступности: он находит оба A::num а также B::num, так что есть неопределенность для компилятора.

Вы можете явно позвонить A::num с :

C::A::num();

Если вы явно пытаетесь позвонить B::numтогда ваш компилятор действительно выдаст ошибку доступа:

C::B::num(); // Error

Вы также можете явно ввести базовое имя в область видимости в производном классе, что устранит неоднозначность:

struct C : public A, private B
{
using A::num;
};
6

Другие решения

Чтобы помочь компилятору, вы можете сделать это

 struct C : public A, private B
{
using A::num;
};
3

Частные члены намеренно рассматриваются для разрешения перегрузки.

Предположим, у вас есть

class C {
public:
static void f(int);
static void g();
private:
static void f(long);
};

void C::g() {
f(0L); // okay
}
void g() {
f(0L); // error, does not silently call f(int)
}

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

Создание такого кода ошибки считалось менее хлопотным, чем альтернатива.

1
По вопросам рекламы [email protected]