Note that there are some explanatory texts on larger screens.

plurals
  1. POambiguous template pattern matching when using variadic template arguments of function overloads
    primarykey
    data
    text
    <p>This should be a common situation with variadic templates for example when tree walking children that are variadic template arguments. I find many related questions and answers but either they are about a slightly different thing or they are the same thing and I did not get it. Now to the problem. I have a non variadic tuple like this</p> <pre><code>template &lt;class E, class T1, class T2, class T3, etc...&gt; struct X; </code></pre> <p>and I am overloading functions to have specialized behaviour depending on the first element of such tuple being pointer type or vector pointer type. That works fine but if I pack the template arguments into a single variadic template argument, then the overloads become ambiguous. Here is the error message:</p> <pre><code>variadic.cpp:42:17: error: ambiguous overload for ‘operator&lt;&lt;’ in ‘std::cout &lt;&lt; y’ variadic.cpp:42:17: note: candidates are:... </code></pre> <p>The compiler should prefer <code>X&lt;vector&lt;V*&gt;*,T*...&gt;</code> over <code>X&lt;H*,T*...&gt;</code> when it tries to match <code>vector&lt;double*&gt;*</code> as first element of the tuple.</p> <p>I can disambiguate using enable_if and things work again. However I would like to understand the error and if possible find other means then enable_if. Here is the code:</p> <pre><code>#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;boost/type_traits/is_fundamental.hpp&gt; #include &lt;boost/utility/enable_if.hpp&gt; using namespace std; template &lt;typename ... T&gt; struct X; template &lt;&gt; struct X &lt;&gt; { }; template &lt;typename H, typename ... T&gt; struct X&lt;H*,T*...&gt; : public X&lt;T*...&gt; { H* value; X(H* value, T*... args) : value(value), X&lt;T*...&gt;(args...) { } }; template &lt;typename H, typename ... T&gt; #ifdef DO_NOT_WANNA_SEE_THE_BUG typename boost::enable_if&lt;boost::is_fundamental&lt;H&gt;, std::ostream&gt;::type&amp; operator&lt;&lt;(std::ostream&amp; stream, X&lt;H*,T*...&gt; const &amp; x) #else std::ostream&amp; operator&lt;&lt;(std::ostream&amp; stream, X&lt;H*,T*...&gt; const &amp; x) #endif { return stream &lt;&lt; "specialized scalar pointer"; } template &lt;typename V, typename ... T&gt; std::ostream&amp; operator&lt;&lt;(std::ostream&amp; stream, X&lt;vector&lt;V*&gt;*,T*...&gt; const &amp; x) { return stream &lt;&lt; "specialized vector pointer"; } int main() { double a,b; vector&lt;double *&gt; v; X&lt;double*,double*&gt; x (&amp;a,&amp;b); X&lt;vector&lt;double*&gt;*, double*&gt; y (&amp;v, &amp;b); cout &lt;&lt; x &lt;&lt; endl; cout &lt;&lt; y &lt;&lt; endl; // this line is ambiguous according to gcc 4.6 and later } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload