4

I have the following struct with a variadic constructor with a default argument:

struct S {
    template<typename... Args>
    S(int n=0, Args&& ...args) {}
};

int main() {
    S s1;       // fine on clang and g++ (S(0) by default argument, empty Args)
    S s2(1);    // fine on clang and g++ (S(1), empty Args)
    S s3(1, 2); // fine on g++ (S(1, 2), non-empty Args), clang complains (see below)
}

As indicated, S(1, 2) compiles fine on g++ (version 7.3, tested with flags -std=c++1z and -std=c++14), but clang (version 6.0.0, tested with the same flags) tells me the following:

<source>:3:26: error: missing default argument on parameter 'args'
    S(int n=0, Args&& ...args) {}
                         ^
<source>:9:7: note: in instantiation of function template specialization 'S::S<int>' requested here
    S s3(1, 2); // fine on g++ (S(1, 2), non-empty Args), clang complains (see below)
      ^

I already found Can parameter pack function arguments be defaulted? which deals with a similar problem, but covers only the case where the parameter list is completely empty (i.e. S s()). I am particularly interested in the case S(1, 2).

The standard says:

In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration or shall be a function parameter pack.

So I thought that my constructor for S was valid and the values for n and args could be deduced in all three cases. Which compiler (if any) is correct?

phimuemue
  • 34,669
  • 9
  • 84
  • 115
  • Compiles fine in MSVC 15.6.2. Could be that Clang reads the instantiated function as `S(int n = 0, int deduced) {}` and somehow fails to see it as a parameter pack, thinking it is invalid since the following argument has no default. – Carl Mar 20 '18 at 15:54
  • @Barry I think the other question deals with an empty parameter list, but I am particularly interested in the `S(1, 2)` case. – phimuemue Mar 20 '18 at 16:01
  • 1
    @phimuemue The other question deals with the concept of having a trailing function parameter pack after a defaulted argument... the actually call is immaterial. Your code is completely correct and the linked question has clang bug reports. – Barry Mar 20 '18 at 16:11
  • 1
    @Barry Thank you for the reply. You are right: The bug report (https://bugs.llvm.org/show_bug.cgi?id=23029#c3) has something similar to my example. – phimuemue Mar 20 '18 at 16:21

0 Answers0