#5098 closed Patches (fixed)
[result_of] decltype-based result_of cannot handle rvalue-reference correctly
| Reported by: | 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)
Change History (7)
by , 12 years ago
| Attachment: | result_of.patch added |
|---|
by , 12 years ago
| Attachment: | result_of_test.patch added |
|---|
A patch against trunk (libs/utility/test/result_of_test.cpp)
comment:1 by , 12 years ago
Replying to mimomorin@…:
boost::result_of<func(int)>::typeissigned char(which should beunsigned 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 , 12 years ago
| Owner: | changed from to |
|---|---|
| Type: | Bugs → Patches |
comment:3 by , 12 years ago
| Owner: | changed from to |
|---|
comment:4 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
comment:5 by , 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!

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