Opened 11 years ago
Last modified 10 years ago
#6278 new Bugs
mem_fn has a different result_type
Reported by: | Owned by: | Peter Dimov | |
---|---|---|---|
Milestone: | To Be Determined | Component: | bind |
Version: | Boost 1.48.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The following code does not compile:
/* <URL: file://localhost/usr/share/doc/packages/boost-1.44.0/libs/bind/mem_fn.html#Purpose > All function objects returned by mem_fn expose a result_type typedef that represents the return type of the member function. For data members, result_type is defined as the type of the member. */ typedef int type_of_the_member; struct U { type_of_the_member m; }; template < class F > typename F ::result_type U_m (F const &t, U &u) { typedef typename F:: result_type r; typedef type_of_the_member r; typename F:: result_type r1; return t (u); } U u; int x ((U_m (::boost ::mem_fn (&U ::m), u)));
codepad says: error: conflicting declaration 'typedef type_of_the_member r'
Change History (4)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
It's true that result_type is defined as a const reference instead of a plain type, but what does this have to do with whether the type is copyable or not? result_of<F(U&)> is not necessarily M&, by the way. U can be a pointer or a smart pointer to a const pointee. What specific problem are you having?
comment:3 by , 11 years ago
If result_type were plain, as it allegedly is, and the type of the member were noncopyable then returning it from a function would be a problem.
Specific problem:
- you cannot copy into a
transform_iterator
when the transform selects a reference to a member by means ofmem_fn
.
If I may digress a bit, I suppose that the reason why the standard does not provide an analogue for mem_fun_ref
for data members is that accessing data members is discouraged in C++. Having come to that conclusion, I added the necessary accessors to the underlying class and used just mem_fun_ref
, eradicating mem_fn
completely.
comment:4 by , 10 years ago
The error is normal as you have declared twice the type r :(
typedef typename F:: result_type r; typedef type_of_the_member r;
It is unwise for
mem_fn
to defineresult_type
at all. The type of the member need not even be copyable. Instead, it should be arranged so thatboost:: result_of < F (U &) >:: type
betype_of_the_member &
boost:: result_of < F (U const &) >:: type
betype_of_the_member const &