#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)>::type
issigned 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)