2010-05-14 32 views
27

Gần đây tôi đã nhận thấy một lớp trong C++ 0x yêu cầu một hàm tạo mặc định rõ ràng. Tuy nhiên, tôi không thể đưa ra một kịch bản trong đó một hàm tạo mặc định có thể được gọi ngầm định. Nó có vẻ giống như một specifier khá vô nghĩa. Tôi nghĩ có lẽ nó sẽ không cho phép Class c; ủng hộ Class c = Class(); nhưng điều đó có vẻ không đúng.Mục đích của các nhà xây dựng mặc định rõ ràng

Một số trích dẫn có liên quan từ C++ 0x FCD, vì nó là dễ dàng hơn cho tôi để điều hướng [văn bản tương tự tồn tại trong C++ 03, nếu không phải ở các vị trí tương tự]

12.3.1.3 [ class.conv.ctor]

Một hàm tạo mặc định có thể là một hàm tạo rõ ràng; một hàm tạo như vậy sẽ được sử dụng để thực hiện khởi tạo mặc định hoặc khởi tạo giá trị (8.5).

Nó tiếp tục cung cấp một ví dụ về hàm tạo mặc định rõ ràng, nhưng nó chỉ bắt chước ví dụ tôi đã cung cấp ở trên.

8.5.6 [decl.init]

Để mặc định khởi tạo một đối tượng kiểu T có nghĩa là:

- nếu T là một (có thể cv-đủ điều kiện) kiểu lớp (khoản 9) , hàm tạo mặc định cho T được gọi (và khởi tạo là không đúng định dạng nếu T không có hàm tạo mặc định có thể truy cập được);

; 8.5.7 [decl.init]

Để giá trị khởi tạo một đối tượng kiểu T có nghĩa là:

- nếu T là một (có thể cv-đủ điều kiện) kiểu lớp (khoản 9) với một constructor do người dùng cung cấp (12.1), sau đó hàm tạo mặc định cho T được gọi (và khởi tạo là không đúng định dạng nếu T không có hàm tạo mặc định có thể truy cập được);

Trong cả hai trường hợp, lệnh gọi chuẩn cho hàm tạo mặc định sẽ được gọi. Nhưng đó là điều sẽ xảy ra nếu hàm tạo mặc định không rõ ràng. Cho đầy đủ vì:

8.5.11 [decl.init]

Nếu không khởi tạo được quy định cho một đối tượng, đối tượng là mặc định-khởi tạo;

Từ những gì tôi có thể biết, điều này chỉ để lại chuyển đổi không có dữ liệu. Mà không có ý nghĩa. Điều tốt nhất tôi có thể đưa ra sẽ là như sau:

void function(Class c); 
int main() { 
    function(); //implicitly convert from no parameter to a single parameter 
} 

Nhưng rõ ràng đó không phải là cách C++ xử lý đối số mặc định. Còn gì khác có thể khiến explicit Class(); hoạt động khác với Class();?

Ví dụ cụ thể tạo ra câu hỏi này là std::function [20.8.14.2 func.wrap.func]. Nó đòi hỏi một số nhà xây dựng chuyển đổi, không ai trong số đó được đánh dấu rõ ràng, nhưng constructor mặc định là.

+0

Ngay sau khi tôi đăng bài, tôi nghĩ tôi đã đưa ra một lời giải thích. Nhưng tôi sẽ chờ đợi để xác nhận những nghi ngờ của tôi, vì điều này có vẻ như là một câu hỏi hữu ích dù sao đi nữa. –

Trả lời

21

này tuyên bố một constructor mặc định rõ ràng:

struct A { 
    explicit A(int a1 = 0); 
}; 

A a = 0; /* not allowed */ 
A b; /* allowed */ 
A c(0); /* allowed */ 

Trong trường hợp không có tham số, như trong ví dụ sau, explicit là không cần thiết.

struct A { 
    /* explicit is redundant. */ 
    explicit A(); 
}; 

Trong một số dự thảo C++ 0x, tôi tin rằng đó là n3035, nó làm cho một sự khác biệt theo cách sau:

A a = {}; /* error! */ 
A b{}; /* alright */ 

void function(A a); 
void f() { function({}); /* error! */ } 

Nhưng trong FCD, họ changed this (tuy nhiên, tôi nghi ngờ rằng họ không có lý do đặc biệt này trong tâm trí) trong đó cả ba trường hợp giá trị khởi tạo đối tượng tương ứng. Khởi tạo giá trị không làm điệu nhảy có độ phân giải quá tải và do đó sẽ không thất bại đối với các nhà xây dựng rõ ràng.

+0

OK. Sau đó, hàm khởi tạo rõ ràng cho 'std :: function' chỉ đơn giản là giữ lại từ phiên bản của bản nháp đó? Đó là lời giải thích mà cuối cùng tôi đã tìm ra sau khi viết câu hỏi, nhưng không phải ví dụ được cung cấp cũng như 'std :: function()' lấy một tham số tùy chọn, vì vậy tôi không hoàn toàn bị thuyết phục. –

+0

Điều này dường như đã thay đổi một chút, xem [CWG 1518] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518). Các phiên bản gần đây của g ++ và clang ++ từ chối 'function ({})' đối với các hàm tạo mặc định không mặc định, ngay cả trong chế độ C++ 11. – dyp

+0

Xem thêm http://cplusplus.github.io/LWG/lwg-defects.html#2510 –

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