Opened 11 years ago

Last modified 10 years ago

#6278 new Bugs

mem_fn has a different result_type

Reported by: giecrilj@… 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 giecrilj@…, 11 years ago

It is unwise for mem_fn to define result_type at all. The type of the member need not even be copyable. Instead, it should be arranged so that

  • boost:: result_of < F (U &) >:: type be type_of_the_member &
  • boost:: result_of < F (U const &) >:: type be type_of_the_member const &

comment:2 by Peter Dimov, 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 giecrilj@…, 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 of mem_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 viboes, 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;
Note: See TracTickets for help on using tickets.