2017-09-29 21 views
6

Tôi có lớpMặc định lập luận cho phép xây dựng để gọi phương thức riêng

class A 
{ 
public: 
    class Key 
    { 
     Key() {} 
     Key(Key const &) {} 
    }; 

    A(Key key, int a = 5) {} 
}; 

Các nhà xây dựng cho Key là tư nhân, để không ai sẽ có thể xây dựng một đối tượng A. Tuy nhiên, với đoạn mã sau:

int main() { 
    A a(A::Key()); // this compiles !!! 
    A a2(A::Key(), 5); // this doesn't 
    // somehow defaulting the argument causes the private constructor 
    // to be OK - no idea why 
    return 0; 
} 

Bằng cách sử dụng của các đối số mặc định cho int a trong constructor của tôi, trình biên dịch hạnh phúc biên dịch sử dụng của tôi của A::Key() mặc dù thực tế rằng nó là tư nhân. Tuy nhiên, nếu tôi đưa ra giá trị cho a, trình biên dịch sẽ nhận ra rằng tôi đang cố gắng sử dụng một hàm tạo riêng và các lỗi. Tại sao điều này? Có someway để buộc trình biên dịch để lỗi ra cho ví dụ đầu tiên là tốt?

Xem here để biết ví dụ trực tiếp.

Trả lời

7

Điều này là do phân tích cú pháp gây tranh cãi nhất.

A a(A::Key()); 

Không tạo ra một A tên a và xây dựng nó với một tạm thời A::Key. Nó tạo ra một hàm a trả về một A và lấy một con trỏ chưa được đặt tên cho hàm trả về một A::Key.

Nếu bạn thêm một cặp ngoặc đơn để nó, bạn sẽ nhận được một lỗi biên dịch

A a((A::Key())); 

đó bạn đang cố gắng gọi một constructor tin. Ngoài ra, bạn có thể sử dụng khởi tạo thống nhất, đồng thời làm nổi bật lỗi đó và sẽ gây ra lỗi biên dịch

A a(A::Key{}); 
+1

Tôi biết tôi đã thấy điều này trước đây ... một trong những điều tôi gặp phải 5 năm một lần và bị lúng túng bởi vì Tôi đã không nhìn thấy nó trong quá lâu ... Cảm ơn sự giúp đỡ. –

+1

@R_Kapp Không sao, vui lòng trợ giúp. – NathanOliver

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