2017-05-17 18 views
16

Trong đoạn mã sau, GCC 7 với chế độ C++ 1z gọi hàm khởi tạo mặc định, nhưng GCC/C++ 14 và Clang/C++ 14, C++ 1z gọi hàm khởi tạo-list.tại sao `S x ({})` gọi hàm tạo mặc định trong chế độ GCC 7/C++ 1z?

Hành vi này có bị ảnh hưởng bởi bất kỳ thay đổi C++ 1z Specifiation nào (có thể là Guaranteed copy elision?) Hoặc lỗi GCC không?

#include <cstdio> 
#include <initializer_list> 

struct S { 
    S() { std::printf("DEF "); }  // (1) 
    S(std::initializer_list<int> il) // (2) 
    { std::printf("L=%zu ", il.size()); } 
}; 

int main() { 
    S x({}); 
} 

Output:

Trả lời

17

Tôi nghĩ rằng đây là một lỗi gcc (nộp như 80804). Trình tự các quy tắc cho [dcl.init] trong C++ 17 là:

Nếu loại đích là một (có thể cv-đủ điều kiện) kiểu lớp:

  • Nếu biểu thức khởi tạo là một prvalue và phiên bản cv-unqualified của loại nguồn là cùng lớp với lớp đích, biểu thức khởi tạo được sử dụng để khởi tạo đối tượng đích.

Dấu đầu tiên đó không áp dụng. Biểu thức khởi tạo ở đây là {}, thậm chí không phải là một biểu thức để nó thậm chí không có loại cv không đủ tiêu chuẩn để so sánh với S. Dấu đầu dòng này sẽ áp dụng nếu chúng tôi đã viết S x(S{}) thay thế.

  • Ngược lại, nếu việc khởi tạo là trực tiếp khởi tạo, hoặc nếu nó là bản sao-khởi nơi các phiên bản cv-không đủ tiêu chuẩn của các loại nguồn là lớp giống như, hay một lớp dẫn xuất của, lớp của đích đến, các nhà thầu được xem xét. Các hàm tạo được áp dụng được liệt kê ([over.match.ctor]), và cái tốt nhất được chọn thông qua độ phân giải quá tải. Hàm khởi tạo để chọn được gọi để khởi tạo đối tượng, với biểu thức khởi tạo hoặc biểu thức-danh sách làm đối số của nó. Nếu không có hàm tạo nào được áp dụng, hoặc độ phân giải quá tải là mơ hồ, thì việc khởi tạo bị hỏng.

Đây là trực tiếp khởi tạo, vì vậy nhà xây dựng được coi là mỗi [over.match.ctor], mà chỉ nói là quá tải trên các nhà thầu. Vì có một hàm tạo std::initializer_list, nên hàm đó được ưu tiên cho mỗi [over.ics.rank], do đó, nó được chọn.


Sự khác biệt duy nhất giữa C++ 14 và C++ 17 ở đây là phần giới thiệu của dấu đầu dòng - không áp dụng, vì vậy hành vi phải giống nhau.

+9

Lỗi tràn, nơi các lỗi trình biên dịch được tìm thấy từ các câu hỏi bất thường. – InternetAussie

+2

@InternetAussie vấn đề là không phải ai cũng gửi báo cáo lỗi –

+0

@ShafikYaghmour Thật vậy, nhưng ít nhất một số người như Barry rất tử tế để chủ động gửi những vấn đề này cho những người có thể sửa chúng!Cảm ơn vì điều đó. –

Các vấn đề liên quan