http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59481
Bug ID: 59481 Summary: late-specified return type using a parameter pack doesn't work with a recursive function template Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ville.voutilainen at gmail dot com Test snippet: template<typename T> int func (T) { return 0; } template<typename T, typename... Ts> auto func (T t, Ts... ts) -> decltype (func (ts...)) // -> decltype (func ((Ts)ts...)) // ^ workaround { return func<Ts...> (ts...); } int main (int argc, char *argv[]) { func (1, 2); } This gives edoceo4.cpp: In substitution of ‘template<class T, class ... Ts> decltype (func(func::ts ...)) func(T, Ts ...) [with T = int; Ts = {}]’: edoceo4.cpp:9:28: required from ‘decltype (func(func::ts ...)) func(T, Ts ...) [with T = int; Ts = {int}; decltype (func(func::ts ...)) = int]’ edoceo4.cpp:15:13: required from here edoceo4.cpp:5:51: error: expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs auto func (T t, Ts... ts) -> decltype (func (ts...)) ^ The dump_expr diagnostic is certainly suspicious. Clang 3.4 accepts the code. Another user reports that 4.6 with --c++0x accepts the code too. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37729 may be related, but the case is not identical, and that one has been fixed. In a similar but not identical fashion, template<typename T> int func (T) { return 0; } template<typename T, typename... Ts> auto func (T t, Ts... ts) -> decltype (func (ts...)); template<typename T, typename... Ts> auto func (T t, Ts... ts) -> decltype (func (ts...)) { return func (ts...); } int main (int argc, char *argv[]) { func (1,2,3); } doesn't compile, it produces edoceo6.cpp: In function ‘int main(int, char**)’: edoceo6.cpp:16:14: error: no matching function for call to ‘func(int, int, int)’ func (1,2,3); ^ edoceo6.cpp:16:14: note: candidates are: edoceo6.cpp:2:5: note: template<class T> int func(T) int func (T) { return 0; } ^ edoceo6.cpp:2:5: note: template argument deduction/substitution failed: edoceo6.cpp:16:14: note: candidate expects 1 argument, 3 provided func (1,2,3); ^ edoceo6.cpp:8:6: note: template<class T, class ... Ts> decltype (func(func::ts ...)) func(T, Ts ...) auto func (T t, Ts... ts) -> decltype (func (ts...)) ^ edoceo6.cpp:8:6: note: template argument deduction/substitution failed: edoceo6.cpp: In substitution of ‘template<class T, class ... Ts> decltype (func(func::ts ...)) func(T, Ts ...) [with T = int; Ts = {int, int}]’: edoceo6.cpp:16:14: required from here edoceo6.cpp:5:51: error: no matching function for call to ‘func(int&, int&)’ auto func (T t, Ts... ts) -> decltype (func (ts...)); ^ edoceo6.cpp:5:51: note: candidate is: edoceo6.cpp:2:5: note: template<class T> int func(T) int func (T) { return 0; } ^ edoceo6.cpp:2:5: note: template argument deduction/substitution failed: edoceo6.cpp:5:51: note: candidate expects 1 argument, 2 provided auto func (T t, Ts... ts) -> decltype (func (ts...)); ^ Clang 3.4 again accepts the code.