Boost logo

Boost :

Subject: Re: [boost] [result_of] now uses decltype on release branch
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2012-09-03 14:16:17


On Sep 1, 2012, at 8:12 PM, Joel de Guzman wrote:

> On 9/2/12 7:24 AM, Eric Niebler wrote:
>>
>> We will have to make a very BOLD announcement in the release notes of
>> 1.52. Not only will users of Phoenix be affected; anybody who relies on
>> boost::result_of to use the TR1 protocol will be broken by this. This
>> might be a painful transition for some, but there's no helping that.
>
> I have no problem with this as long as there's clear documentation
> on what users would expect and how to deal with them in their code.

Below is a first stab at documenting breaking changes for the release notes and/or result_of documentation. Is there anything I'm missing? Any caveats regarding N3276? Is this too much? Too little?

BREAKING CHANGES TO BOOST RESULT_OF

On compilers that adequately implement C++11 decltype (clang 3.1, gcc 4.7, Visual C++ 11), result_of now uses decltype by default to deduce return types rather than following the TR1 result_of protocol, which is no longer required. While this makes result_of much more useful, it also necessitates new behaviors which will break some existing code.

The following are use-cases where result_of behaves differently depending on whether decltype is used. The macro BOOST_RESULT_OF_USE_DECLTYPE is defined when result_of is using decltype. Please see the result_of documentation for more information.

1) TR1 protocol misusage

When using the TR1 protocol, result_of cannot tell whether the actual type of a call to a function object is the same as the type specified by the protocol, which allows for the possibility of inadvertent mismatches between the specified type and the actual type. When using decltype, these subtle bugs will be detected and may result in compilation errors.

struct functor {
    typedef short result_type;
    int operator()(short);
};

#ifdef BOOST_RESULT_OF_USE_DECLTYPE

BOOST_STATIC_ASSERT((
    is_same<result_of<functor(short)>::type, int>::value
));

#else

BOOST_STATIC_ASSERT((
    is_same<result_of<functor(short)>::type, short>::value
));

#endif

2) Nullary function objects

When using the TR1 protocol, result_of cannot always deduce the type of calls to nullary function objects, in which case the type defaults to void. When using decltype, result_of always gives the actual type of the call expression.

Example:

struct functor {
    template<class> struct result {
        typedef int type;
    };
    int operator()();
};

#ifdef BOOST_RESULT_OF_USE_DECLTYPE

BOOST_STATIC_ASSERT((
    is_same<result_of<functor()>::type, int>::value
));

#else

BOOST_STATIC_ASSERT((
    is_same<result_of<functor()>::type, void>::value
));

#endif

3) Non-class prvalues and cv-qualification

When using the TR1 protocol, result_of will report the cv-qualified type specified by the result_type or result<> members, regardless of the actual cv-qualification of the call expression. When using decltype, result_of will report the actual type of the call expression, which is not cv-qualified when the expression is a non-class prvalue.

Example:

struct functor {
    template<class> struct result;
    template<class F, class T> struct result<F(const T)> {
        typedef const T type;
    };

    const short operator()(const short);
    int const & operator()(int const &);
};

// Non-prvalue call expressions work the same with or without decltype.

BOOST_STATIC_ASSERT((
    is_same<
        result_of<functor(int const &)>::type,
        int const &
>::value
));

// Non-class prvalue call expressions are not actually cv-qualified,
// but only the decltype-based result_of reports this accurately.

#ifdef BOOST_RESULT_OF_USE_DECLTYPE

BOOST_STATIC_ASSERT((
    is_same<
        result_of<functor(const short)>::type,
        short
>::value
));

#else

BOOST_STATIC_ASSERT((
    is_same<
        result_of<functor(const short)>::type,
        const short
>::value
));

#endif

- Daniel


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