2014-12-01 15 views
5

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) 

DEMO

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?

+0

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

+0

@Columbo: C++ 11 13.3.3.1/4 –

+0

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) –

Trả lời

1

Từ ngữ bị lỗi và được thay đổi bằng C++ 14. Bây giờ [over.best.ics]/4 reads

Tuy nhiên, nếu mục tiêu là

  • tham số đầu tiên của một nhà xây dựng hoặc
  • [...]

và các nhà xây dựng hoặc người dùng xác định chức năng chuyển đổi là một ứng cử viên bởi

  • 13.3.1.3, khi lập luận là tạm thời trong bước thứ hai của một lớp sao chép khởi,
  • 13.3.1.4, 13.3.1.5 hoặc 13.3.1.6 (trong mọi trường hợp), hoặc
  • sự giai đoạn thứ hai của 13.3.1.7 khi danh sách initializer có đúng một phần tử, và mục tiêu là tham số đầu tiên của một nhà xây dựng của lớp X, và việc chuyển đổi là để X hoặc tham chiếu đến (có thể cv-đủ điều kiện) X,

người dùng các chuỗi chuyển đổi được xác định không được xem xét. [Lưu ý: Những quy tắc này ngăn không cho nhiều chuyển đổi do người dùng xác định được áp dụng trong quá trình phân giải quá tải, do đó tránh việc đệ quy vô hạn. - cuối note]

Việc chuyển B() để int không thuộc phạm của thành viên này - các cụm từ in đậm chỉ appertains đến các ràng buộc của một tham chiếu đến một tạm thời trong quá trình sao chép khởi tạo.
Tuy nhiên, Clang rejects this sample code theo như trên:

class A; 

struct B 
{ 
    operator A(); 
}; 

struct A 
{ 
    A(A const&){} 
}; 

A a{B()}; 
+0

Tuyệt vời, cảm ơn bạn !!! –

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