Boost logo

Boost :

Subject: Re: [boost] [result_of] decltype and function objects
From: David Abrahams (dave_at_[hidden])
Date: 2008-11-14 00:28:43

on Thu Nov 13 2008, Eric Niebler <> wrote:

> I've noticed test failures when compiling some of boost in C++0x mode due to the
> change to boost::result_of to use decltype. The problem comes from function objects
> like this:
> template<class T>
> struct identity
> {
> typedef T result_type;
> T const & // <== problem here
> operator()(T const &t) const
> {
> return t;
> }
> };
> In this (overly simplistic) example, we just want to return what is passed in. The
> computed type (result_type) is different than the return type of operator() ... and
> for a good (IMO) reason: to avoid an unnecessary copy in some cases. The idea is to
> accommodate usage like this:
> result_of<identity(BigObj)>::type i = identity()(BigObj());
You need a template argument here---------------^

> It is really very important that decltype(i) be BigObj, and not BogObj
> const &, which would cause a dangling reference.
> But with the change to use decltype in
> boost::result_of, the dangling reference is exactly what I would get.

It seems like you're expecting the line above to act like

   auto i = identity<BigObj>()(BigObj());

but that's not what result_of is supposed to do. It is supposed to
tells you, in excruciating detail, about the return type of the function

> Am I now forced to change identity::operator() return by value here?

Either that or change your expectations about the right way to declare i.

> That seems sub-optimal to me. In many other potential uses of identity
> (e.g., when forwarding the result to some other function), the copy is
> totally unnecessary.

Ah, well. The optimal safe way to write an identity function is of

    template <class T>
    T identity(T x)
        return boost::move(x);

which on any decent compiler should cause no copies provided T is
move-enabled, and only one if it isn't.

Dave Abrahams
BoostPro Computing

Boost list run by bdawes at, gregod at, cpdaniel at, john at