Sự khác biệt có thể được giảm xuống còn
struct A { explicit A(int); };
struct B { B(int); };
void f(A);
void f(B);
int main() {
f({ 1 });
}
On GCC này không thành công, phù hợp với các tiêu chuẩn (mà nói rằng đối với danh sách khởi tạo, nhà xây dựng rõ ràng được coi là - vì vậy họ có thể mang lại một sự mơ hồ - nhưng họ chỉ không được phép chọn). Clang chấp nhận nó và gọi hàm thứ hai.
Trong trường hợp của bạn, những gì @Columbo nói trong câu trả lời của mình là Direct list initialization compiles successfully, but normal direct initialization fails, why? sẽ được áp dụng. Với sự khác biệt trong trường hợp của bạn, B(const B&);
không còn được Clang chấp nhận vì chuyển đổi {0} -> B
sẽ phải đối mặt với hai khả năng: hàm tạo rõ ràng hoặc sử dụng hàm tạo bản sao đệ quy lần thứ hai. Tùy chọn đầu tiên, như được giải thích ở trên, sẽ không được xem xét bởi clang và lần này giải thích bởi @Columbo được áp dụng và không thể sử dụng hàm tạo bản sao lần thứ hai vì điều đó cần chuyển đổi do người dùng xác định vì chúng tôi có một phần tử duy nhất (ở đây, 0
). Vì vậy, trong bản tóm tắt, chỉ có các nhà xây dựng đầu tiên thành công và được thực hiện.
Vì tôi hiểu vấn đề là về các quy tắc giải quyết quá tải lạ và một số có thể không tuân theo, đây là giải thích trực quan hơn. Các quy tắc đang hoạt động là, để
Vì vậy cho GCC nó có thể sử dụng các nhà xây dựng rõ ràng trực tiếp, và ngoài ra bởi việc sử dụng duy nhất của các nhà xây dựng bản sao. Đối với clang, nó chỉ xem xét việc sử dụng trực tiếp constructor rõ ràng, và nó sẽ không sử dụng nó gián tiếp bởi một bản sao-list-initialization bằng cách sử dụng constructor sao chép như GCC. Cả hai sẽ không cân nhắc việc sử dụng hàm tạo bản sao lần thứ hai và nó không liên quan ở đây.
Nguồn
2015-10-10 16:52:02
Bản sao của http://stackoverflow.com/q/32469979/3647361? – Columbo
@Columbo 'B (A)' là rõ ràng ở đây và http://stackoverflow.com/questions/32469979/direct-list-initialization-compiles-successfully-but-normal-direct-initializati cả gcc và clang có cùng kết quả nhưng đây là khác nhau. – stackcpp
Tôi đoán là do các tiêu chuẩn mặc định khác nhau/hỗ trợ chuẩn. –