Rationale

| Home | Libraries | People | FAQ | More

## Rationale

### Why do I have to specify the presence of a destructor explicitly?

When using references the destructor isn't needed. By not assuming it implicitly, we allow capturing types with private or protected destructors by reference. For the sake of consistency, it must be specified when capturing by value as well.

### Why non-member functions?

The members of `any` can be customized. By using free functions, we guarantee that we don't interfere with anything that a user might want.

### Why are the placeholders called `_a`, `_b` and not `_1` `_2`

An earlier version of the library used the names `_1`, `_2`, etc. instead of `_a`, `_b`, etc. This caused a certain amount of confusion because the numbered placeholders are already used with a somewhat different meaning by several other libraries including Boost/Std Bind, Boost.Phoenix, and Boost.MPL. I eventually decided that since the placeholders represented named parameters instead of positional parameters, letters were more appropriate than numbers.

### Why not use `boost::ref` for references?

Boost.Function allows you to use `boost::ref` to store a reference to a function object. However, in the general case treating references and values in the same way causes inconsistent behavior that is difficult to reason about. If Boost.TypeErasure handled references like this, then, when you copy an `any`, you would have no idea whether the new object is a real copy or just a new reference to the same underlying object. Boost.Function can get away with it, because it doesn't expose any mutating operations on the stored function object.

Another method that has been proposed is only to keep a reference the first time.

    int i = 2;
    any x = ref(i);
    any y = x; // makes a copy

Unfortunately, this doesn't handle all use cases, as there is no reliable way to return such a reference from a function. In addition it adds overhead whether it's needed or not, as we would have to add a flag to any to keep track of whether or not it is storing a reference. (The alternate method of storing this in the "`clone`" method in the vtable is impossibly complex to implement given the decoupled vtables that Boost.TypeErasure uses and it still adds overhead.).