Interaction between default arguments and parameter package (GCC and clang disagree)

I expect the following code to be compiled:

#include <iostream> template <class Tag = void, class T = int, class... Args> void print(T val = T{}, Args... args) { std::cout << val << ' ' << sizeof...(args) << std::endl; } int main() { print(); print(3.14); print(0, 1, 2); } 

While it compiles to GCC 5.2 (C ++ 11), despite the warnings of unused-but-set-parameter , clang 3.6 (C ++ 11) gives the following error messages:

 main.cpp:4:33: error: missing default argument on parameter 'args' void print(T val = T{}, Args... args) { ^ main.cpp:11:5: note: in instantiation of function template specialization 'print<void, int, int, int>' requested here print(0, 1, 2); ^ main.cpp:4:33: error: missing default argument on parameter 'args' void print(T val = T{}, Args... args) { ^ 2 errors generated. 

So who is right?

+6
source share
2 answers

They are both correct, in a way.

There is an error in the standard, CWG 1609 , which makes it unclear whether the code is well-formed or not.

In the CWG summary, there seems to be a consensus that clang should be correct in refusing code. Then, a few months later, consensus was reached that the GCC should be correct in adopting the code. So who knows what will happen in C ++ 17.

+4
source

Well, as @TC pointed out in the comment and answer of @LightnessRacesinOrbit, this is an unresolved CWG problem. Anyway, I just found a workaround:

 #include <iostream> template <class Tag = void, class T, class... Args> void print(T val, Args... args) { std::cout << val << ' ' << sizeof...(args) << std::endl; } template <class Tag = void, class T = int> void print(T val = T{}) { std::cout << val << ' ' << 0 << std::endl; } int main() { print(); print(3.14); print(0, 1, 2); } 
0
source

All Articles