Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::unary_function doesn't contain virtual destructor

I came across class template std::unary_function and std::binary_function.

template <class Arg, class Result>
struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
};

template <class Arg1, class Arg2, class Result>
struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
};

Both these can be used as base class for specific purposes. But still there's no virtual destructor in these. One reason which I could guess is these are not meant to be treated polymorphically. i.e

std::unary_function* ptr; 
//intialize it 
//do something
delete ptr;

But if that is so, shouldn't destructor be there with protected access specifier so that compiler would break any attempt to do that.

like image 471
ravi Avatar asked Dec 14 '22 17:12

ravi


2 Answers

In a well-balanced C++ design philosophy the idea of "preventing" something from happening is mostly applicable when there's a good chance of accidental and not-easily-detectable misuse. And even in that case the preventive measures are only applicable when they don't impose any significant penalties. The purpose of such classes as unary_function, binary_function, iterator etc. should be sufficiently clear to anyone who knows about them. It would take a completely clueless user to use them incorrectly.

In case of classes that implement the well-established idiom of "group member injection" through public inheritance, adding a virtual destructor to the would be a major design error. Turning a non-polymorphic class into a polymorphic one is a major qualitative change. Paying such price for the ability to use this idiom would be prohibitively unacceptable.

A non-virtual protected destructor is a different story... I don't know why they didn't go that way. Maybe it just looked unnecessarily excessive to add a member function to that purpose alone (since otherwise, these classes contain only typedefs).

Note that even though unary_function, binary_function are deprecated, iterator is not. The deprecation does not target the idiom itself. The idiom is widely used within other larger-scale design approaches, like C++ implementation of Mixins and such.

like image 191
AnT Avatar answered Jan 08 '23 23:01

AnT


Because std::unary_function and std::binary_function are, by design, not supposed to be used for polymorphic deletion : they exist only to provide typedefs to the child classes, and have no other intent.

Being a base class in C++ does not mean that the class must exhibit any particular polymorphic behaviour.

i.e. you should never see code such as :

void foo(std::unary_function* f)
{
     delete f; // illegal
}

Note that both classes are deprecated since C++11 (See N3145)

like image 43
quantdev Avatar answered Jan 08 '23 23:01

quantdev