Подтвердить что ты не робот

Оператор виртуального явного преобразования, переопределяющий

У меня есть класс Base, определяющий explicit operator bool:

struct Base {
    virtual explicit operator bool() const {
        return true;
    }
};

И у меня есть подкласс Derived, определяющий operator bool:

struct Derived : Base {
    operator bool() const override {
        return false;
    }
};

Как вы можете заметить, Derived::operator bool явно не помечен explicit, но отмечен override, поэтому я ожидал, что компилятор будет жаловаться. Однако, как gcc, так и clang, похоже, согласны с тем, что это действительно. Было ли мое ожидание необоснованным?

Кроме того, если я использую классы следующим образом, TakesBool(base) не компилируется (как ожидалось), но TakesBool(derived) делает:

void TakesBool(bool b) {}

int main() {
    //Base base;     TakesBool(base); // compilation error (as expected)
    Derived derived; TakesBool(derived);
    return 0;
}

Это, по-видимому, указывает на то, что Derived имеет (не explicit) operator bool, который, однако, помечен override без объявления virtual. Как это возможно?

4b9b3361

Ответ 1

Вы можете подумать, что не explicit operator bool в Derived не отменяет explicit operator bool в Base, нет, он делает. Явный спецификатор не имеет значения, он не является частью сигнатуры функции.

Из стандарта $10.3/2 Виртуальные функции [Class.virtual]:

(акцент мой)

Если виртуальная функция-член vf объявлена ​​в классе Base и в классе Derived, полученном прямо или косвенно из Base, функция-член vf с с тем же именем, параметр-type-list ([dcl.fct]), cv-qualification и ref-qualifier (или отсутствие такого же) как Base::vf объявлен, тогда Derived::vf также является виртуальным (независимо от того, так объявлено) и он переопределяет Base::vf.

Таким образом, компилятор будет жаловаться только тогда, когда имя, параметр-тип-список, cv-qualification или ref-qualifier функции не совпадают, явный спецификатор не будет рассмотрен.


Вы сказали "отмечен override без объявления virtual", обратите внимание, что объявление virtual для функции-члена в производном классе не имеет значения, что также будет virtual.