This code recently stopped compiling. (I have a remove_cv on top of the remove_reference in the original code but it didn't look necessary to reproduce the problem) #include <utility> #include <tuple> #include <type_traits> struct A { template<class...U,class= typename std::enable_if< !std::is_same< std::tuple<typename std::remove_reference<U>::type...>, std::tuple<A> >::value >::type > A(U&&...u) ; }; int main(){ A a(1,2,3); } bug.cc: In function ‘int main()’: bug.cc:16:11: error: no matching function for call to ‘A::A(int, int, int)’ bug.cc:13:13: note: candidates are: template<class ... U, class> A::A(U&& ...) bug.cc:4:8: note: constexpr A::A(const A&) bug.cc:4:8: note: constexpr A::A(A&&)
Let's add Jason. I'm pretty sure this isn't a library issue because the same happens with just: template<class...U> struct tuple; and outside std::tuple the rest is pretty trivial as far as the library is concerned.
Note that if I change the function to: template<class...U,class= typename std::enable_if< !std::is_same< std::tuple<U&&...>, void >::value >::type > A(U&&...u) ; I get: sorry, unimplemented: use of 'type_pack_expansion' in template
It is caused by revision 166179: http://gcc.gnu.org/ml/gcc-cvs/2010-11/msg00065.html
I think what's happening is, at some point during template parameters fixup (to build proper canonical types for dependent parms) we try to substitute the U template parameter pack [and the the remaining unamed template parm] into the pattern of the default argument std::remote_reference<U>::type... . The TYPENAME_TYPE case of tsubst then logically calls tsubst_aggr_type on 'std::remote_reference<U>'. That later function in turn calls lookup_template_class with std::remote_reference as argument to D1 and a TYPE_PACK_EXPANSION built for the template parameter U (by template_parm_to_arg) and argument to ARGLIST. At that point we are trying to match a template argument which is a pack expansion with a template parameter that is not a parameter pack - and we hit http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35722. So I think I am going to focus on that bug and see.
Actually my previous analysis wasn't quite right. Rather, the substitution of the fixed up U into std::remove_reference<U>::type..., fails. It fails because we fail to compare the fixed up U with the non-fixed up U. And after that the sky falls. So this has nothing to do with http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35722, luckily. Pheew. A candidate patch was sent to to http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00295.html along with a smaller reproducer.
Author: dodji Date: Sun Feb 20 17:37:03 2011 New Revision: 170341 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170341 Log: PR c++/46394 gcc/cp/ PR c++/46394 * pt.c (tsubst_pack_expansion): do not use cp_tree_equal/same_type_p to detect an expansion of a parameter pack. gcc/testsuite/ PR c++/46394 * g++.dg/template/typedef38.C: New test. Added: trunk/gcc/testsuite/g++.dg/template/typedef38.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Fixed in trunk (4.6).
Really close the bug.