Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Rationale

Why do I have to specify the presence of a destructor explicitly?
Why non-member functions?
Why are the placeholders called _a, _b and not _1 _2
Why not use boost::ref for references?

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.

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.

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.

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.).


PrevUpHomeNext