Boost C++ Libraries: Ticket #1396: wrong result_of invocation around transform_view https://svn.boost.org/trac10/ticket/1396 <p> See the following snippet. For some reason, <code>boost::result_of&lt; ::identity(int) &gt;</code> is invoked in <code>as_vector</code>, which means that the argument is rvalue. It should be <code>boost::result_of&lt; ::identity(int &amp;) &gt;</code>. </p> <pre class="wiki">#include &lt;boost/fusion/include/as_vector.hpp&gt; #include &lt;boost/fusion/include/transform_view.hpp&gt; #include &lt;boost/fusion/include/vector.hpp&gt; struct identity { template&lt;class FunCall&gt; struct result; template&lt;class Fun&gt; struct result&lt;Fun(int&amp;)&gt; { typedef int&amp; type; }; int&amp; operator()(int&amp; i) const { return i; } }; int main() { typedef boost::fusion::vector&lt;int, int&gt; from_t; from_t from; boost::fusion::transform_view&lt;from_t, ::identity&gt; v(from, ::identity()); boost::fusion::as_vector(v); // doesn't compile. } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/1396 Trac 1.4.3 anonymous Thu, 22 Nov 2007 01:36:19 GMT <link>https://svn.boost.org/trac10/ticket/1396#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:1</guid> <description> <p> There needs to be a specialization for both Fun(int&amp;) and Fun(int): </p> <pre class="wiki"> struct identity { template &lt;typename FunCall&gt; struct result; template &lt;typename Fun&gt; struct result&lt;Fun(int&amp;)&gt; { typedef int&amp; type; }; template &lt;typename Fun&gt; struct result&lt;Fun(int)&gt; { typedef int&amp; type; }; int&amp; operator()(int&amp; i) const { return i; } }; </pre><p> or better yet: </p> <pre class="wiki"> struct identity { template &lt;typename FunCall&gt; struct result; template &lt;typename Fun, typename T&gt; struct result&lt;Fun(T)&gt; { typedef typename boost::add_reference&lt;T&gt;::type type; }; template &lt;typename T&gt; T&amp; operator()(T&amp; i) const { return i; } }; </pre><p> This deserves some explanation. Here's why: </p> <p> Your initial vector is: </p> <pre class="wiki"> vector&lt;int, int&gt; </pre><p> The underlying types are int and int (hint: not int&amp;). 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: </p> <pre class="wiki"> int, int </pre><p> then your identity transform is applied calling </p> <pre class="wiki"> result&lt;Fun(int)&gt; </pre><p> hence, the result: </p> <pre class="wiki"> int&amp;, int&amp; </pre><p> Now... </p> <p> 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&amp;. 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: </p> <pre class="wiki"> result&lt;Fun(int&amp;)&gt; </pre><p> Why doesn't STL iterators have this? It does! It's the value_type. Now if only std::vector&lt;T&amp;&gt; is allowed, then the both the value_type and the reference_type would be T&amp;. </p> <p> Aha! now this is starting to sound like a FAQ :-) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 22 Nov 2007 02:31:24 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/1396 https://svn.boost.org/trac10/ticket/1396 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">transform.cpp</span> </li> </ul> Ticket anonymous Thu, 22 Nov 2007 02:32:29 GMT <link>https://svn.boost.org/trac10/ticket/1396#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:2</guid> <description> <p> Here's a more generic identity transform that works for mpl sequences too, FWIW (attached) </p> </description> <category>Ticket</category> </item> <item> <author>Shunsuke Sogame <pstade.mb@…></author> <pubDate>Thu, 29 Nov 2007 02:24:02 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/1396 https://svn.boost.org/trac10/ticket/1396 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">value_of_transform_view_defect.cpp</span> </li> </ul> <p> A defect report of this problem </p> Ticket Shunsuke Sogame <pstade.mb@…> Thu, 29 Nov 2007 02:28:05 GMT <link>https://svn.boost.org/trac10/ticket/1396#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/1396#comment:2" title="Comment 2">anonymous</a>: </p> <blockquote class="citation"> <p> Here's a more generic identity transform that works for mpl sequences too, FWIW (attached) </p> </blockquote> <p> BTW, according to language lawyers, this identity isn't allowed under TR1, because it is not consistent with decltype. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 29 Nov 2007 02:49:25 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1396#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:4</guid> <description> <p> IMO, you are wrong. It is correct. The example you have in the boost list thread certainly is ill formed. The example I have here is not. </p> <p> I've followed the thread (<a class="ext-link" href="http://tinyurl.com/298abt"><span class="icon">​</span>http://tinyurl.com/298abt</a>) but what you missed is the template. The T in Fun(T) is generic and can accommodate references too. This(int) does not. </p> <p> If you want to avoid dangling references, you can write it as: </p> <pre class="wiki"> struct identity { template&lt;class FunCall&gt; struct result; template &lt;class Fun, class T&gt; struct result&lt;Fun(T&amp;)&gt; { typedef T&amp; type; }; template &lt;class Fun, class T&gt; struct result&lt;Fun(T const&amp;)&gt; { typedef T type; }; template &lt;class T&gt; T&amp; operator()(T&amp; val) const { return val; } template &lt;class T&gt; T operator()(T const&amp; val) const { return val; } }; </pre> </description> <category>Ticket</category> </item> <item> <author>Shunsuke Sogame <pstade.mb@…></author> <pubDate>Thu, 29 Nov 2007 02:58:42 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1396#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/1396#comment:4" title="Comment 4">anonymous</a>: </p> <blockquote class="citation"> <p> IMO, you are wrong. It is correct. The example you have in the boost list thread certainly is ill formed. The example I have here is not. </p> </blockquote> <p> Ah, right. Unless identity in transform.cpp takes a rvalue, it is ok. Sorry for my confusing. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 29 Nov 2007 03:06:14 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1396#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:6</guid> <description> <p> :-) Anyway, I am really convinced that your proposal to add the <a class="missing wiki">MetafunctionClass</a> <code>ValueOf</code> for value_of implementation is the best way to go. It will be added :-) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joel de Guzman</dc:creator> <pubDate>Thu, 29 Nov 2007 03:07:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1396#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:7</guid> <description> <p> Ooops. Didn't log in. The last two "anonymous" posts are mine (Joel) </p> </description> <category>Ticket</category> </item> <item> <author>Shunsuke Sogame <pstade.mb@…></author> <pubDate>Thu, 29 Nov 2007 03:15:42 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1396#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1396#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/1396#comment:6" title="Comment 6">anonymous</a>: </p> <blockquote class="citation"> <p> :-) Anyway, I am really convinced that your proposal to add the <a class="missing wiki">MetafunctionClass</a> <code>ValueOf</code> for value_of implementation is the best way to go. It will be added :-) </p> </blockquote> <p> Please consider it carefully. I'm sometimes wrong :-) Thanks to your patience for my broken english, I have a temporary(cheating) workaround for this problem. Therefore, Fusion professionals have plenty of time to consider. </p> <p> Regards, </p> </description> <category>Ticket</category> </item> </channel> </rss>