Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#5098 closed Patches (fixed)

[result_of] decltype-based result_of cannot handle rvalue-reference correctly

Reported by: mimomorin@… Owned by: Daniel Walker
Milestone: To Be Determined Component: utility
Version: Boost Development Trunk Severity: Problem
Keywords: result_of decltype Cc:

Description

The implementation of decltype-based boost::result_of is essentially the same as

// This code is taken from N1454 (author: Douglas Gregor)
template <typename F, typename T1, typename T2, ..., typename TN>
class result_of<F(T1, T2, ..., TN)> {
    static F f;
    static T1 t1;
    static T2 t2;
         .
         .
         .
    static TN tN;
    
public:
    // Note: even if Ti is rvalue reference, ti is treated as lvalue.
    typedef decltype(f(t1, t2, ..., tN)) type;
};

So, the implementation cannot handle rvalue-reference correctly (it becomes lvalue).

For example, in the following code

struct func
{
    unsigned char operator()(int&&     ) { return 0; }
      signed char operator()(int&      ) { return 0; }
             char operator()(int const&) { return 0; }
};

boost::result_of<func(int)>::type is signed char (which should be unsigned char).

I will attach a patch for fixing this issue. The patch uses declval rather than static members.

Attachments (2)

result_of.patch (2.0 KB ) - added by mimomorin@… 12 years ago.
A patch against trunk (boost/utility/result_of.hpp, boost/utility/detail/result_of_iterate.hpp)
result_of_test.patch (1.9 KB ) - added by mimomorin@… 12 years ago.
A patch against trunk (libs/utility/test/result_of_test.cpp)

Download all attachments as: .zip

Change History (7)

by mimomorin@…, 12 years ago

Attachment: result_of.patch added

A patch against trunk (boost/utility/result_of.hpp, boost/utility/detail/result_of_iterate.hpp)

by mimomorin@…, 12 years ago

Attachment: result_of_test.patch added

A patch against trunk (libs/utility/test/result_of_test.cpp)

in reply to:  description comment:1 by mimomorin@…, 12 years ago

Replying to mimomorin@…:

boost::result_of<func(int)>::type is signed char (which should be unsigned char).

This is a typo (though this sentence is still true).

What I meant is:

boost::result_of<func(int&&)>::type is signed char (which should be unsigned char).

comment:2 by mimomorin@…, 12 years ago

Owner: changed from No-Maintainer to Daryle Walker
Type: BugsPatches

comment:3 by mimomorin@…, 12 years ago

Owner: changed from Daryle Walker to Daniel Walker

comment:4 by Daniel Walker, 12 years ago

Resolution: fixed
Status: newclosed

(In [68373]) use declval to fix #5098

comment:5 by Daniel Walker, 12 years ago

I applied the patches with one modification: instead of defining its own declval, it uses boost::declval. Thanks for input and patches!

Note: See TracTickets for help on using tickets.