默认参数和参数包之间的交互(GCC和clang不同意)

时间:2015-12-28 13:50:14

标签: c++ templates c++11 variadic-templates default-arguments

我希望编译以下代码:

#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);
}

尽管有unused-but-set-parameter警告,它在GCC 5.2(C ++ 11)上编译,但是clang 3.6(C ++ 11)给出了以下错误消息:

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.

那么,谁是对的?

2 个答案:

答案 0 :(得分:5)

从某种意义上说,它们都是正确的。

标准中存在一个错误CWG 1609,不清楚代码是否格式正确。

在CWG摘要中,似乎有一个共识,即clang 应该在拒绝代码时是正确的。然后,几个月后,人们一致认为GCC 应该接受代码是正确的。那么谁知道C ++中会发生什么17。

答案 1 :(得分:0)

好吧,就像@ T.C.已经在@LightnessRacesinOrbit的评论和答案中指出,这是一个待定的CWG问题。无论如何,我刚刚找到了一个解决方法:

#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);
}