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.

Reply via email to