Note that there are some explanatory texts on larger screens.

plurals
  1. POstd::tuple_cat substitution failure
    primarykey
    data
    text
    <p>I use <code>std::tuple_cat</code> to do subset selections of argument lists into tuples, like so:</p> <pre><code>template &lt;class...&gt; struct odds; template &lt;class T1&gt; struct odds&lt;T1&gt; { typedef std::tuple&lt;T1&gt; type; static type value(T1&amp;&amp; t1) { return std::make_tuple(std::forward&lt;T1&gt;(t1)); } }; template &lt;class T1, class T2&gt; struct odds&lt;T1, T2&gt; { typedef std::tuple&lt;T1&gt; type; static type value(T1&amp;&amp; t1, T2&amp;&amp;) { return std::make_tuple(std::forward&lt;T1&gt;(t1)); } }; template &lt;class T1, class T2, class... TTail&gt; struct odds&lt;T1, T2, TTail...&gt; { typedef decltype(std::tuple_cat(T1(), typename odds&lt;TTail...&gt;::type())) type; // L32 static type value(T1&amp;&amp; t1, T2&amp;&amp;, TTail&amp;&amp;... rest) { return std::tuple_cat(std::forward&lt;T1&gt;(t1), odds&lt;TTail...&gt;::value(std::forward&lt;TTail&gt;(rest)...)); // L35 } }; </code></pre> <p>, with the following as a test case:</p> <pre><code>// assume &lt;tuple&gt;, &lt;utility&gt; are included at top of file template &lt;class... T&gt; auto foo(T... x) -&gt; typename odds&lt;T...&gt;::type { return odds&lt;T...&gt;::value(x...); //... } int main() { auto bar = foo(5, true, 6, false); // L46 auto baz = odds&lt;int, bool, int, bool&gt;::value(5, true, 6, false); // L47 // bar, baz should be tuple&lt;int,int&gt; with value { 5, 6 } } </code></pre> <p>However, template deduction issues arise in both clang-3.1 and gcc-4.7.2:</p> <p>Clang output:</p> <pre><code>test.cc:32:19: error: no matching function for call to 'tuple_cat' typedef decltype(std::tuple_cat(T1(), typename odds&lt;TTail...&gt;::type())) type; ^~~~~~~~~~~~~~ test.cc:40:30: note: in instantiation of template class 'odds&lt;int, bool, int, bool&gt;' requested here auto foo(T... x) -&gt; typename odds&lt;T...&gt;::type ^ test.cc:40:6: note: while substituting deduced template arguments into function template 'foo' [with T = &lt;int, bool, int, bool&gt;] auto foo(T... x) -&gt; typename odds&lt;T...&gt;::type ^ /usr/include/c++/v1/tuple:1063:1: note: candidate template ignored: substitution failure [with _Tuple0 = int, _Tuples = &lt;std::__1::tuple&lt;int&gt;&gt;] tuple_cat(_Tuple0&amp;&amp; __t0, _Tuples&amp;&amp;... __tpls) ^ /usr/include/c++/v1/tuple:987:1: note: candidate function not viable: requires 0 arguments, but 2 were provided tuple_cat() ^ test.cc:46:13: error: no matching function for call to 'foo' auto bar = foo(5, true, 6, false); ^~~ test.cc:40:6: note: candidate template ignored: substitution failure [with T = &lt;int, bool, int, bool&gt;] auto foo(T... x) -&gt; typename odds&lt;T...&gt;::type ^ test.cc:35:10: error: no matching function for call to 'tuple_cat' return std::tuple_cat(std::forward&lt;T1&gt;(t1), odds&lt;TTail...&gt;::value(std::forward&lt;TTail&gt;(rest)...)); ^~~~~~~~~~~~~~ test.cc:47:41: note: in instantiation of member function 'odds&lt;int, bool, int, bool&gt;::value' requested here auto baz = odds&lt;int, bool, int, bool&gt;::value(5,true,6,false); ^ /usr/include/c++/v1/tuple:1063:1: note: candidate template ignored: substitution failure [with _Tuple0 = int, _Tuples = &lt;std::__1::tuple&lt;int&gt;&gt;] tuple_cat(_Tuple0&amp;&amp; __t0, _Tuples&amp;&amp;... __tpls) ^ /usr/include/c++/v1/tuple:987:1: note: candidate function not viable: requires 0 arguments, but 2 were provided tuple_cat() ^ 3 errors generated. </code></pre> <p>Gcc output:</p> <pre><code>test.cc: In instantiation of ‘struct odds&lt;int, bool, int, bool&gt;’: test.cc:40:6: required by substitution of ‘template&lt;class ... T&gt; typename odds&lt;T ...&gt;::type foo(T ...) [with T = {int, bool, int, bool}]’ test.cc:46:34: required from here test.cc:32:74: error: no matching function for call to ‘tuple_cat(int, odds&lt;int, bool&gt;::type)’ test.cc:32:74: note: candidate is: In file included from test.cc:1:0: /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/tuple:1027:5: note: template&lt;class ... _Tpls, class&gt; constexpr typename std::__tuple_cat_result&lt;_Tpls ...&gt;::__type std::tuple_cat(_Tpls&amp;&amp; ...) /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/tuple:1027:5: note: template argument deduction/substitution failed: /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.2/include/g++-v4/tuple:1024:31: error: no type named ‘type’ in ‘struct std::enable_if&lt;false, void&gt;’ test.cc: In function ‘int main()’: test.cc:46:34: error: no matching function for call to ‘foo(int, bool, int, bool)’ test.cc:46:34: note: candidate is: test.cc:40:6: note: template&lt;class ... T&gt; typename odds&lt;T ...&gt;::type foo(T ...) test.cc:40:6: note: substitution of deduced template arguments resulted in errors seen above test.cc:46:34: error: unable to deduce ‘auto’ from ‘&lt;expression error&gt;’ test.cc:47:13: error: ‘value’ is not a member of ‘odds&lt;int, bool, int, bool&gt;’ test.cc:47:61: error: unable to deduce ‘auto’ from ‘&lt;expression error&gt;’ </code></pre> <p>Gcc is a bit more helpful here, especially with the error</p> <pre><code> test.cc:32:74: error: no matching function for call to ‘tuple_cat(int, odds&lt;int, bool&gt;::type)’ </code></pre> <p>The goal is to call a function which recursively unpacks arguments, collects the selections into a collecting tuple, and returns it. To accumulate it in a flat manner, I'm using <code>std::tuple_cat()</code> to flatten the recursive tail tuple, add a head, and return the tuple. Forwarding is used in order to not drop reference qualifiers during recursion. </p> <p>Later on in the code, the resulting tuple is unpacked to call a different variadic function, but that's outside the scope of this error.</p> <p>Clearly, I've omitted some subtle yet crucial detail somewhere, but I am finding significant difficulty in tracking down the underlying issue.</p>
    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.
    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