8

Gần đây tôi đã viết một lớp rất đơn giản.std :: initializer_list loại khấu trừ

class C 
{ 
public: 
    void AddString(std::initializer_list<std::pair<const char*,int>> x) 
    { 
      //irrelevant 
    } 
}; 

int main() 
{ 
      C c; 
      c.AddString({ {"1",1}, {"2", 2}, {"3", 3} }); 
      .... //other unimportant stuff 
      return 0; 
} 

Thật ngạc nhiên thú vị khi được biên soạn và hoạt động chính xác. Có thể ai đó xin vui lòng giải thích cho tôi như thế nào trình biên dịch đã có thể suy ra các initialized brested lồng nhau đã cho một std::pair? Tôi đang sử dụng MSVS 2013.

Trả lời

9
c.AddString({ {"1",1}, {"2", 2}, {"3", 3} }); 

Bạn đang đi qua một chuẩn bị tinh thần-init-list, mà bản thân nó chứa lồng nhau cú đúp-init-list s để AddString. Đối số có thể khớp với tham số std::initializer_list<std::pair<const char*,int>> nếu bên trong braced-init-list s có thể được chuyển đổi thành std::pair<const char*,int>.

Quá trình phân giải quá tải này diễn ra theo hai bước; lần đầu tiên một nỗ lực được thực hiện để phù hợp với các nhà thầu của std::pair có tham số std::initializer_list. Vì std::pair không có hàm tạo như vậy, bước thứ hai xảy ra, trong đó các hàm tạo khác của std::pair<const char*,int> được liệt kê với các đối số char const[2]int. Điều này sẽ khớp với hàm tạo pair sau bởi vì char const[2] được chuyển đổi hoàn toàn thành char const * và bản thân hàm tạo không phải là explicit.

template< class U1, class U2 > 
constexpr pair(U1&& x, U2&& y); 

Trích dẫn N3337 §13.3.1.7/1 [over.match.list]

Khi đối tượng của phi tổng hợp lớp loại T là danh sách khởi tạo (8.5.4), độ phân giải quá tải chọn hàm khởi tạo theo hai pha:
— Ban đầu, các hàm ứng cử viên là các hàm tạo danh sách khởi tạo (8.5.4) của lớp T và danh sách đối số bao gồm initializ er danh sách như là một đối số duy nhất.
Nếu không tìm thấy hàm khởi tạo danh sách khởi tạo khả thi, thì hàm phân giải quá tải được thực hiện lại, trong đó hàm ứng viên là tất cả các hàm tạo của lớp T và danh sách đối số bao gồm các phần tử của danh sách khởi tạo.

Nếu danh sách trình khởi tạo không có phần tử và T có hàm tạo mặc định, thì pha đầu tiên bị bỏ qua. Trong bản sao-danh sách khởi tạo, nếu một nhà xây dựng explicit được chọn, khởi tạo là hình thành không hợp lệ.

+0

Câu trả lời hay, hoàn chỉnh hơn nhiều! – vsoftco

+0

Cảm ơn bạn, làm rõ một số điều .. Tôi cần phải hiểu thêm một chút về độ phân giải quá tải khi các danh sách init được chuẩn bị có liên quan. – pebbleonthebeach

+0

@pebbleonthebeach Các quy tắc về độ phân giải quá tải khi danh sách khởi tạo có liên quan là những gì tôi đã sao chép ở trên. Nếu bạn có nghĩa là bạn cần làm quen với độ phân giải quá tải nói chung, tôi khuyên bạn nên bắt đầu với [video này] (https://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-Cpp-3-of-n) (xem toàn bộ chuỗi nếu bạn có thể tìm thấy thời gian). – Praetorian

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