1

I have the following code:

struct Processor
{
    template <typename... ARGS>
    void OnMsg(ARGS... args, int) {}
    // but makine ARGS after int is fine:
    // void OnMsg(int, ARGS... args) {}
};

struct Dispatcher
{
    void Register(void (Processor::*memfun)(int)) {}
};

void Register(Dispatcher& dispatcher)
{
    dispatcher.Register(&Processor::OnMsg<>);
}

GCC >4.7.1 compiles this just fine. Clang (any) does not, because it cannot instantiate the "no-args" version of the OnMsg function.

17 : <source>:17:26: error: address of overloaded function 'OnMsg' does not match required type 'void (int)'
    dispatcher.Register(&Processor::OnMsg<>);
                         ^~~~~~~~~~~~~~~~~~
5 : <source>:5:10: note: candidate template ignored: failed template argument deduction
    void OnMsg(ARGS... args, int) {}
         ^
12 : <source>:12:37: note: passing argument to parameter 'memfun' here
    void Register(void (Processor::*memfun)(int)) {}
                                    ^
1 error generated.
Compiler exited with result code 1

Curiously enough, if you move the ARGS... in the OnMsg function to the end of the arguments (to the right of int), it works in clang.

Godbolt link: https://godbolt.org/g/cJwXC7

Which compiler is right?

Anton
  • 1,458
  • 1
  • 14
  • 28
  • 2
    Argument deduction only works when the variadic argument is in the last position of the arguments list. – Remy Lebeau Dec 07 '17 at 09:27
  • The SO posts I've come across assert this for template argument parameters, but they didn't mention anything about function arguments. 14.8.2: "A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list of the function template or has a default argument". So it means I cannot do `template foo(T t, ARGS... args);`. But what about `template foo(ARGS... args, T t);`? – Anton Dec 08 '17 at 00:21
  • 1
    Variadic function parameters must ALWAYS be in the last position, templated or otherwise. – Remy Lebeau Dec 08 '17 at 00:26
  • OK: so GCC is being non-compliant in this case. – Anton Dec 08 '17 at 00:27
  • 1
    Yes. Not surprising, since GCC tends to support additional extensions that other compilers do not. – Remy Lebeau Dec 08 '17 at 00:28
  • Do you want to write this as your answer and I can accept it? I went searching around again with better search terms and found this: https://stackoverflow.com/a/42027161/4130137 – Anton Dec 08 '17 at 00:36

0 Answers0