6

Im folgenden einfachen Code-Fragment gelöscht wird:Clang beschwert „kann nicht eine gelöschte Funktion außer Kraft setzen“, während keine Funktion

#include <cstddef> 

struct B 
{ 
    virtual ~B() = default; 
    static void operator delete(void *, int); 
    static void * operator new(size_t, int); 
}; 

struct C : B 
{ 
    virtual ~C() = default; 
}; 

Klirren 3.7 beklagt, dass „nicht-gelöschte Funktion‚~ C‘nicht eine gelöschte Funktion außer Kraft setzen kann“

Weder Visual Studio noch GCC melden einen Fehler in diesem Code. Ist es ein klingender Defekt oder was?

+0

mit korrekten Signaturen, es kompiliert – sp2danny

+1

Ich gehe davon aus, dass Clang sie auf der Grundlage des dritten Aufzählungspunkt lehnt in [\ [class.dtor \]/5] (http://eel.is/c+ + Entwurf/class.dtor # 5). Ich bin mir nicht ganz sicher, ob das die richtige Lektüre ist. –

+0

ist es richtig, es nicht zu kompilieren, aber die Fehlermeldung ist weniger als hilfreich – sp2danny

Antwort

8
static void operator delete(void *, int); 

Nein, es ist

static void operator delete(void *, std::size_t); 

und diese Art Unterschied verursacht eine Mehrdeutigkeit, die relevant wird:

cppreference.com has

Die implizit deklarierte oder notleidenden destructor zum Klasse T ist undefined (bis C++ 11) als gelöscht definiert (da C++ 11), wenn eine der folgenden Punkte zutrifft:

[...]

Die implizit deklarierte destructor ist virtuell (weil die Basisklasse einen virtuellen Destruktor hat) und die Suche nach der Aufhebung der Zuordnung function (operator delete() führt zu einem Aufruf der mehrdeutigen, gelöschten, oder unzugänglichen Funktion.

Und im Standard (Entwurf n4140) §12.4 das ist

5 A destructor für eine Klasse X vorbelegt ist als gelöscht definiert, wenn:

[...]

(5.3) oder, für einen virtuellen Destruktor, Nachschlagen der Nicht-Array Freigabe-Funktion führt zu einer Mehrdeutigkeit oder in einer Funktion, die gelöscht oder nicht zugänglich ist, aus dem Standard-Destruktor.