2015-12-28 17 views
6

tôi mong đợi đoạn mã sau để biên dịch:Sự tương tác giữa đối số mặc định và gói thông số (GCC và kêu vang không đồng ý)

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

Trong khi nó biên dịch trên GCC 5.2 (C++ 11) mặc dù unused-but-set-parameter cảnh báo, Clang 3.6 (C++ 11) cung cấp các thông báo lỗi sau:

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. 

Vì vậy, ai là đúng?

+0

@RIAD Tôi cho rằng trường hợp mặc định cho 'args' là nó không tồn tại chút nào. – Lingxi

+0

Có vấn đề cốt lõi về vấn đề này, IIRC. –

+4

Đúng, [CWG 1609] (http://wg21.link/CWG1609). –

Trả lời

4

Cả hai đều chính xác, theo nghĩa nào đó.

Có lỗi trong tiêu chuẩn, CWG 1609, làm cho nó không rõ liệu mã có được tạo đúng hay không.

Trên bản tóm tắt CWG, có vẻ như có sự nhất trí rằng clang nên là chính xác khi từ chối mã. Sau đó, một vài tháng sau, có một sự nhất trí rằng GCC nên là chính xác khi chấp nhận mã. Vì vậy, ai biết điều gì sẽ xảy ra trong C++ 17.

+0

IMHO, mã là chính xác về mặt logic. – Lingxi

0

Vâng, như @ T.C. đã chỉ ra trong bình luận và câu trả lời của @LightnessRacesinOrbit, đây là một vấn đề CWG đang chờ xử lý. Dù sao, tôi chỉ tìm thấy cách giải quyết:

#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); 
} 
Các vấn đề liên quan