Re: [Boost-bugs] [Boost C++ Libraries] #1396: wrong result_of invocation around transform_view

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #1396: wrong result_of invocation around transform_view
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2007-11-22 01:36:19


#1396: wrong result_of invocation around transform_view
----------------------------------------------------+-----------------------
  Reporter: Shunsuke Sogame <pstade.mb_at_[hidden]> | Owner: djowel
      Type: Bugs | Status: new
 Milestone: Boost 1.35.0 | Component: fusion
   Version: Boost Development Trunk | Severity: Problem
Resolution: | Keywords:
----------------------------------------------------+-----------------------
Comment (by anonymous):

 There needs to be a specialization for both Fun(int&) and
 Fun(int):
 {{{
     struct identity
     {
         template <typename FunCall>
         struct result;

         template <typename Fun>
         struct result<Fun(int&)>
         {
             typedef int& type;
         };

         template <typename Fun>
         struct result<Fun(int)>
         {
             typedef int& type;
         };

         int& operator()(int& i) const
         {
             return i;
         }
     };
 }}}
 or better yet:
 {{{
     struct identity
     {
         template <typename FunCall>
         struct result;

         template <typename Fun, typename T>
         struct result<Fun(T)>
         {
             typedef typename boost::add_reference<T>::type type;
         };

         template <typename T>
         T& operator()(T& i) const
         {
             return i;
         }
     };
 }}}
 This deserves some explanation. Here's why:

 Your initial vector is:
 {{{
     vector<int, int>
 }}}
 The underlying types are int and int (hint: not int&).
 Now, when as_vector tries to compute the resulting vector,
 it calls value_of to know the exact type of the elements in
 the input sequence. value_of strips the unnecessary reference
 that deref may potentially add. It just so happens that what
 you return is a reference, but that's irrelevant. The important
 thing is that the input sequence is:
 {{{
     int, int
 }}}
 then your identity transform is applied calling
 {{{
      result<Fun(int)>
 }}}
 hence, the result:
 {{{
     int&, int&
 }}}
 Now...

 We haven't started yet. We merely computed the desired result for
 as_vector. Now the fun begins, the actual conversion starts.
 The input sequence is walked by an iterator. Here, we *deref*
 the iterator --which returns an int&. Now, it's obvious why
 deref returns a reference -- to avoid copies. But then,
 transform_iterator::deref is also called with this reference
 parameter, which ultimately calls the identity transform:
 {{{
      result<Fun(int&)>
 }}}
 Why doesn't STL iterators have this? It does! It's the value_type.
 Now if only std::vector<T&> is allowed, then the both the value_type
 and the reference_type would be T&.

 Aha! now this is starting to sound like a FAQ :-)

--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1396#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.


This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:57 UTC