Các mã sau hoạt động tốt:Tại sao chuyển đổi do người dùng xác định được áp dụng trong quá trình khởi tạo?
#include <iostream>
struct B
{
operator int()
{
return int();
}
};
struct A
{
A(int, int){ std::cout << "A(int, int)" << std::endl; }
};
A a({B(), B()});
int main()
{
}
và tạo đầu ra:
A(int, int)
Nhưng tôi không thể hiểu tại sao? Chuẩn là gì? Nói là:
Tuy nhiên, khi xem xét lập luận của một nhà xây dựng hoặc chức năng chuyển đổi người dùng xác định đó là một ứng cử viên bởi 13.3.1.3 khi gọi cho việc sao chép/di chuyển của tạm thời trong lần thứ hai Bước một bản sao khởi tạo lớp, bằng 13.3.1.7 khi chuyển initializer danh sách dưới dạng đối số đơn hoặc khi danh sách trình khởi tạo có chính xác một phần tử và chuyển đổi sang một số loại X hoặc tham chiếu đến (có thể là cv-đủ điều kiện) X được xem xét cho tham số đầu tiên của một hàm tạo của X [...] chỉ các chuỗi chuyển đổi chuẩn và các chuỗi chuyển đổi dấu chấm lửng được xem xét ed
Vì vậy, trong trường hợp của chúng tôi, chúng tôi coi đối số của hàm tạo (đó là {B(), B()}
). Chính xác hơn, chúng tôi đã chuyển danh sách khởi tạo như một đối số duy nhất (trường hợp thứ hai trong quy tắc tôi đã trích dẫn). Bây giờ, chúng ta cần chuyển đổi phần tử đầu tiên của danh sách khởi tạo (tạm thời là loại B
) thành int
và cách duy nhất để làm điều đó là áp dụng hội tụ do người dùng xác định (B::operator int()
). Tuy nhiên, như đã nói ở cuối quy tắc, tôi đã trích dẫn chỉ trình tự chuyển đổi chuẩn và chuỗi chuyển đổi dấu chấm lửng được xem là. Kể từ đó, mã đó không nên hoạt động, nó sẽ ném các lỗi như A(int, int)
là không khả thi hoặc loại.
Có gì không ổn. Có thể đó là một lỗi?
Không tìm thấy báo giá này ở N4140. Bạn đang trích dẫn bản nháp và đoạn nào? – Columbo
@Columbo: C++ 11 13.3.3.1/4 –
có thể trùng lặp của [Phân biệt giữa chuỗi chuyển đổi do người dùng xác định theo trình tự chuyển đổi chuẩn ban đầu] (http://stackoverflow.com/questions/11555950/distinguishing-between-user -dãy chuyển đổi-chuỗi-theo-chuẩn-ban đầu-chuẩn) –