Hi Everybody,

The standard says (Sect 5.3.5, para 3) that "In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined."

This requirement is sound in general, but it prevents certain usages that although uncommon appear to be valid and could be allowed.

The usage I have in mind is what Mathew Wilson calls "veneers" (see http://synesis.com.au/resources/articles/cpp/veneers.pdf). In short, if I do not like that std::function when default constructed is something that throws upon the call to operator(), I extend it as follows:

template <typename T>
struct Callback : std::function<void(T)>
  Callback() : std::function<void(T)> { [](T){/*ignore*/} } {}

I can pass it by value, convert to std::function without slicing, and it looks it would be safe to do this:

std::function<void(T)> * fun = new Callback;
delete fun;

There is no harm, except that this is defined as UB. Could the rule be relaxed to say that if the derived type is layout-compatible with the base class and its destructor is implicitly declared or explicitly defaulted, the behaviur is well defined?

Or is there a good reason for this restriction?