6

В следующем простом фрагменте коды:Clang жалуется на «не может переопределить удаленную функцию» пока функция не будет удалена

#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; 
}; 

лязг 3.7 жалуется, что «не удаленная функция„~ C“не может переопределить удаленную функцию» : http://goo.gl/Ax6oth

Ни Visual Studio, ни GCC не сообщают об ошибке в этом коде. Это дефект клана или что?

+0

с правильными подписями, он компилирует – sp2danny

+1

Я предполагаю, что Clang отвергает его на основе третьей точки пули в [\ [class.dtor \]/5] (http://eel.is/c+ + проект/class.dtor # 5). Я не совсем уверен, правильное ли это чтение. –

+0

это право не компилировать его, но сообщение об ошибке менее полезно – sp2danny

ответ

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

Нет, это

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

и что разница типа вызывает неоднозначность, которая получает соответствующую:

cppreference.com has

неявно объявленный или просроченный деструктор для Класс Т не определен (до C++ 11) определены как удаленные (так как C++ 11), если какой-либо из верно следующее:

[...]

неявно объявленная деструктор virtual (потому что базовый класс имеет виртуальный деструктор) и поиск функции освобождения (оператор delete() приводит к вызову двусмысленной, удаленной, или недоступной функции.

И в стандарте (проект n4140) §12.4 что

5 дефолт деструктор для класса X определяется как удаляется, если:

[...]

(5.3) или, для виртуального деструктора, поиск функции нераспределения приводит к неоднозначности или функции, которая удалена или недоступна из дефолтного деструктора.