Boost C++ Libraries: Ticket #7364: ambiguity error constructing std::vector from assign::list_of https://svn.boost.org/trac10/ticket/7364 <p> The problem is due to the addition of rvalue-reference container constructors. The following fails to compile with vc10: </p> <pre class="wiki">#include &lt;vector&gt; #include &lt;boost/assign/list_of.hpp&gt; int main() { std::vector&lt;int&gt; i(boost::assign::list_of(1)); } </pre><p> The error is: </p> <pre class="wiki">1&gt;c:\boost\org\trunk\libs\proto\scratch\main.cpp(6): error C2668: 'std::vector&lt;_Ty&gt;::vector' : ambiguous call to overloaded function 1&gt; with 1&gt; [ 1&gt; _Ty=int 1&gt; ] 1&gt; c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(593): could be 'std::vector&lt;_Ty&gt;::vector(std::vector&lt;_Ty&gt; &amp;&amp;)' 1&gt; with 1&gt; [ 1&gt; _Ty=int 1&gt; ] 1&gt; c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(515): or 'std::vector&lt;_Ty&gt;::vector(unsigned int)' 1&gt; with 1&gt; [ 1&gt; _Ty=int 1&gt; ] 1&gt; while trying to match the argument list '(boost::assign_detail::generic_list&lt;T&gt;)' 1&gt; with 1&gt; [ 1&gt; T=int 1&gt; ] 1&gt; 1&gt;Build FAILED. </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7364 Trac 1.4.3 zadirion@… Wed, 19 Sep 2012 15:29:53 GMT <link>https://svn.boost.org/trac10/ticket/7364#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:1</guid> <description> <p> Ok, since my report was closed as a duplicate, I'll be letting people know here that a temporary fix for this is the following: </p> <p> Adding a to_container(dummy) call on the second list_of fixes the issue, where dummy is a dummy object of the same type as the container. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Wed, 19 Sep 2012 15:35:26 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:2</guid> <description> <p> Below is an implementation of <code>list_of</code> that addresses the issue for C++11 compilers. </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;iterator&gt; #include &lt;algorithm&gt; #include &lt;deque&gt; #include &lt;vector&gt; #include &lt;utility&gt; #include &lt;type_traits&gt; template&lt;typename T&gt; using uncvref = typename std::remove_cv&lt;typename std::remove_reference&lt;T&gt;::type&gt;::type; template&lt;typename T&gt; struct generic_list; template&lt;typename T&gt; generic_list&lt;uncvref&lt;T&gt;&gt; list_of(T &amp;&amp; t); template&lt;typename T&gt; struct generic_list { private: std::deque&lt;T&gt; values; friend generic_list&lt;T&gt; list_of&lt;&gt;(T &amp;&amp; t); friend generic_list&lt;T&gt; list_of&lt;&gt;(T &amp; t); friend generic_list&lt;T&gt; list_of&lt;&gt;(T const &amp; t); generic_list() = default; public: generic_list(generic_list &amp;&amp;) = default; generic_list(generic_list const &amp;) = delete; generic_list &amp;operator=(generic_list &amp;&amp;) = delete; generic_list &amp;operator=(generic_list const &amp;) = delete; template&lt;typename U&gt; generic_list &amp; operator()(U &amp;&amp; t) noexcept(noexcept(values.push_back(static_cast&lt;U &amp;&amp;&gt;(t)))) { values.push_back(static_cast&lt;U &amp;&amp;&gt;(t)); return *this; } template&lt;typename Container, typename = decltype(Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())))&gt; operator Container() noexcept(noexcept(Container(Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()))))) { return Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())); } }; template&lt;typename T&gt; inline generic_list&lt;uncvref&lt;T&gt;&gt; list_of(T &amp;&amp; t) { return std::move(generic_list&lt;uncvref&lt;T&gt;&gt;()(static_cast&lt;T &amp;&amp;&gt;(t))); } struct moveable { moveable() = default; moveable(moveable &amp;&amp;) = default; moveable(moveable const &amp;) = delete; moveable &amp;operator=(moveable &amp;&amp;) = default; moveable &amp;operator=(moveable const &amp;) = delete; }; int main() { std::vector&lt;int&gt; i(list_of(1)); std::copy(i.begin(), i.end(), std::ostream_iterator&lt;int&gt;(std::cout, "\n")); std::vector&lt;moveable&gt; j = list_of(moveable())(moveable()); } </pre><p> The trick to fixing the ambiguity error is the defaulted template parameter on <code>operator Container</code> that only allows the conversion if the container can be constructed from a pair of iterators. </p> <p> HTH. </p> </description> <category>Ticket</category> </item> <item> <author>zadirion@…</author> <pubDate>Wed, 26 Sep 2012 09:41:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7364#comment:2" title="Comment 2">eric_niebler</a>: </p> <blockquote class="citation"> <p> Below is an implementation of <code>list_of</code> that addresses the issue for C++11 compilers. </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;iterator&gt; #include &lt;algorithm&gt; #include &lt;deque&gt; #include &lt;vector&gt; #include &lt;utility&gt; #include &lt;type_traits&gt; template&lt;typename T&gt; using uncvref = typename std::remove_cv&lt;typename std::remove_reference&lt;T&gt;::type&gt;::type; template&lt;typename T&gt; struct generic_list; template&lt;typename T&gt; generic_list&lt;uncvref&lt;T&gt;&gt; list_of(T &amp;&amp; t); template&lt;typename T&gt; struct generic_list { private: std::deque&lt;T&gt; values; friend generic_list&lt;T&gt; list_of&lt;&gt;(T &amp;&amp; t); friend generic_list&lt;T&gt; list_of&lt;&gt;(T &amp; t); friend generic_list&lt;T&gt; list_of&lt;&gt;(T const &amp; t); generic_list() = default; public: generic_list(generic_list &amp;&amp;) = default; generic_list(generic_list const &amp;) = delete; generic_list &amp;operator=(generic_list &amp;&amp;) = delete; generic_list &amp;operator=(generic_list const &amp;) = delete; template&lt;typename U&gt; generic_list &amp; operator()(U &amp;&amp; t) noexcept(noexcept(values.push_back(static_cast&lt;U &amp;&amp;&gt;(t)))) { values.push_back(static_cast&lt;U &amp;&amp;&gt;(t)); return *this; } template&lt;typename Container, typename = decltype(Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())))&gt; operator Container() noexcept(noexcept(Container(Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()))))) { return Container(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())); } }; template&lt;typename T&gt; inline generic_list&lt;uncvref&lt;T&gt;&gt; list_of(T &amp;&amp; t) { return std::move(generic_list&lt;uncvref&lt;T&gt;&gt;()(static_cast&lt;T &amp;&amp;&gt;(t))); } struct moveable { moveable() = default; moveable(moveable &amp;&amp;) = default; moveable(moveable const &amp;) = delete; moveable &amp;operator=(moveable &amp;&amp;) = default; moveable &amp;operator=(moveable const &amp;) = delete; }; int main() { std::vector&lt;int&gt; i(list_of(1)); std::copy(i.begin(), i.end(), std::ostream_iterator&lt;int&gt;(std::cout, "\n")); std::vector&lt;moveable&gt; j = list_of(moveable())(moveable()); } </pre><p> The trick to fixing the ambiguity error is the defaulted template parameter on <code>operator Container</code> that only allows the conversion if the container can be constructed from a pair of iterators. </p> <p> HTH. </p> </blockquote> <p> I must point out the fix you posted does not compile in Visual Studio 2012. The templated using syntax and the = default and = delete modifiers are not implemented in VS2012 </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 28 Jan 2013 08:13:07 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:4</guid> <description> <p> How come this hasn't been fixed yet? This is pretty serious. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Wed, 30 Jan 2013 18:17:19 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:5</guid> <description> <p> To be fair to Thorsten, I <em>think</em> this is impossible to fix in C++98. At least, I wasn't able to think of a way. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 01 Aug 2013 04:25:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7364#comment:1" title="Comment 1">zadirion@…</a>: </p> <blockquote class="citation"> <p> Adding a to_container(dummy) call on the second list_of fixes the issue </p> </blockquote> <p> or more succinctly convert_to_container&lt; container_type &gt;(). </p> </description> <category>Ticket</category> </item> <item> <author>Andrey <nikolay@…></author> <pubDate>Tue, 06 Aug 2013 12:32:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:7</guid> <description> <p> Any plans when this issue will be fixed? </p> </description> <category>Ticket</category> </item> <item> <author>asaliheddine@…</author> <pubDate>Tue, 21 Jan 2014 08:59:16 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:8</guid> <description> <p> Hi Guys </p> <p> is there any update on this issue? any fix for VS2012? </p> <p> Thanks Ahmed </p> </description> <category>Ticket</category> </item> <item> <author>abhinuke@…</author> <pubDate>Tue, 07 Apr 2015 13:23:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:9</guid> <description> <p> Hi Guys, </p> <p> Is there any update on this issue? Any fix for VS2013? </p> <p> Thanks, Abhishek D </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Michel Morin</dc:creator> <pubDate>Tue, 07 Apr 2015 14:30:57 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:10</guid> <description> <p> My patch (<a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/5419/assign_cxx0x.patch"><span class="icon">​</span>assign_cxx0x.patch</a>) in <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5419" title="#5419: Patches: assign fails with C++0x compilers (closed: wontfix)">#5419</a> fixes this problem on clang and gcc. I've not tested with VS, but I believe it works fine on VS 2013. </p> </description> <category>Ticket</category> </item> <item> <author>Jim King <jim.king@…></author> <pubDate>Fri, 13 Nov 2015 16:15:24 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:11</guid> <description> <p> Any chance we can get this fix into boost 1.60? I found it solves the issue as well. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 01 Sep 2016 00:45:28 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:12</guid> <description> <p> Is this fixed yet? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 01 Feb 2018 19:42:38 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7364#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:13</guid> <description> <p> Had to use workaround </p> <p> using namespace boost::assign; std::vector&lt;int&gt; data; data += 1,2,3; </p> </description> <category>Ticket</category> </item> <item> <dc:creator>James E. King, III</dc:creator> <pubDate>Mon, 08 Oct 2018 02:24:25 GMT</pubDate> <title>owner changed https://svn.boost.org/trac10/ticket/7364#comment:14 https://svn.boost.org/trac10/ticket/7364#comment:14 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Thorsten Ottosen</span> to <span class="trac-author">James E. King, III</span> </li> </ul> Ticket James E. King, III Mon, 08 Oct 2018 02:24:40 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7364#comment:15 https://svn.boost.org/trac10/ticket/7364#comment:15 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">duplicate</span> </li> </ul> <p> See trac-5419 </p> Ticket James E. King, III Mon, 08 Oct 2018 02:24:59 GMT version, milestone changed https://svn.boost.org/trac10/ticket/7364#comment:16 https://svn.boost.org/trac10/ticket/7364#comment:16 <ul> <li><strong>version</strong> <span class="trac-field-old">Boost Development Trunk</span> → <span class="trac-field-new">Boost 1.53.0</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.69</span> </li> </ul> Ticket James E. King, III Mon, 08 Oct 2018 02:26:22 GMT <link>https://svn.boost.org/trac10/ticket/7364#comment:17 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7364#comment:17</guid> <description> <p> <a class="ext-link" href="https://github.com/boostorg/assign/pull/20"><span class="icon">​</span>https://github.com/boostorg/assign/pull/20</a> </p> </description> <category>Ticket</category> </item> </channel> </rss>