Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2002-01-25 06:06:22


While the standard doesn't require function objects to be assignable, it's a
common (and reasonable) assumption that if you can copy-construct function
object, you can copy-assign it as well. In fact, "assignable" is a key
requirement for a function object that is intended to be used with "smart"
iterators, such filtering iterator adaptor provided by the
'boost::iterator_adaptor' library. Apparently, function objects constructed
(internally) by 'boost::bind' library are exactly that [strange :] -
copyable, but not assignable, - so, for example, writing something like
this:

    boost::make_filter_iterator(
          views.begin()
        , views.end()
        , boost::bind<bool>(std::logical_and<bool>()
            , boost::bind(&view::is_visible, _1)
            , boost::bind(&view::contains, _1, point)
            ) // the predicate is not assignable
        )

is pretty much useless, as the expression returns an iterator object that is
not assignable - i.e. something that is not an iterator at all, at least not
the one that you can use with the standard library algorithms.

That's more, the "copyable, but not assignable" restriction seems to be a
deliberate one, - for example, '_bi::bind_t' objects are intentionally made
non-assignable by declaring the class copy assignment operator private (and
also by declaring private the copy assignment operators of everything else
in the "bind.hpp" header :). While (I think) I can see where the roots of
this restriction began (boost::reference_wrapper<>? :), IMO it's artificial,
limits the applicability of the library, doesn't buy us anything, and,
therefore, should be removed :).

As for 'boost::reference_wrapper<>', here is a proposed modification to make
it meet Assignable requirement (rather simple one, I admit :):

    template<class T> class reference_wrapper
    {
    public:
        explicit reference_wrapper(T & t): t_(&t) {}
        operator T& () const { return *t_; }
        T& get() const { return *t_; }

    private:
        T* t_;
    };

--
Aleksey

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk