2016-08-10 26 views
24

Mam klasy Base wyznaczającą explicit operator bool:wirtualnej wyraźny operator konwersji nadrzędnymi

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

I mam podklasy Derived, określającym operator bool:

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

Jak można zaobserwować, Derived::operator bool jest wyraźnie nie oznaczone explicit, ale oznaczone override, więc spodziewałem się kompilator do złożenia skargi. Jednak zarówno gcc, jak i clang wydają się zgadzać, że jest to poprawne. Czy moje oczekiwania były nieuzasadnione?

Ponadto, jeśli mogę użyć klas w następujący TakesBool(base) nie skompilować (zgodnie z oczekiwaniami), ale TakesBool(derived) robi:

void TakesBool(bool b) {} 

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

Wydaje się to wskazywać, że Derived ma (nie explicit) operator bool, który jest jednak oznaczony jako override bez deklaracji virtual. Jak to jest możliwe?

+1

Jeśli chodzi o brak potrzeby "wirtualnego" w klasie pochodnej, jeśli klasa podstawowa została oznaczona jako "wirtualna", jest domyślnie dorozumiana również dla wszystkich klas pochodnych. Słowo kluczowe "override" jest bardziej wskazówką dla kompilatora, więc nie próbujesz przesłonić funkcji za pomocą innego podpisu (np. Deklarując funkcję w klasie pochodnej, która przyjmuje inne argumenty niż funkcja w klasie bazowej). Zatem te słowa kluczowe są nieistotne dla pytania. –

+1

Wirtualna wysyłka nadal ma miejsce. 'Base * pbase = & deriv; TakesBool ((bool) * pbase); 'wywoła' Derived :: operator bool'. Domyślam się, że 'explicit' nie jest częścią sygnatury funkcji, więc możesz pominąć konwersję' explicit' z tekstem innym niż'exitive '. Nie jestem pewien, czy to zachowanie jest poprawne. –

+0

To jest jak posiadanie funkcji 'protected: virtual' w klasie bazowej z' public: override' w klasie pochodnej. Nie stanowi to żadnego problemu. –

Odpowiedz

17

Można by pomyśleć, że nie- explicitoperator bool w Derived nie zastępują explicitoperator bool w Base, nie, to robi. explicit specifier nie ma znaczenia, nie jest częścią sygnatury funkcji.

od standardu, §10.3/2 Virtual functions [class.virtual]:

(Kopalnia nacisk)

If a virtual member function vf is declared in a class Base and in a class Derived , derived directly or indirectly from Base , a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf .

więc kompilator będzie skarżyć się tylko wtedy, gdy nazwa, parametr typu lista-CV-kwalifikacje lub ref-kwalifikator z funkcja nie jest zgodna, jawny specyfikator nie będzie brany pod uwagę.


powiedział: „oznaczony override bez zgłoszenia virtual”, trzeba pamiętać, że deklaracja virtual dla funkcji członka w klasie pochodnej jest zbędny, to również virtual.

+2

Badałem, że możliwe jest posiadanie klasy bazowej, która ma zarówno 'jawny operator bool', jak i' operator bool', a te dwa są traktowane inaczej. Czy wiesz, co się stanie, jeśli klasa pochodna definiuje 'operator bool() override'? Czy zastępuje on 'operator bool's? – phimuemue

+0

@phimuemue Czemu po prostu nie spróbować? –

+0

@ rainerscore_d Tak, ale przede wszystkim interesuje mnie odpowiedź oparta na standardzie. – phimuemue

Powiązane problemy