2010-02-02 27 views
6

tôi có hệ thống phân cấp sau lớp:C++ Compiler với CRTP

template <typename T> 
class base 
{ 
public: 
    void f() {} 
}; 

class class_a : public base<class_a> {}; 

class class_b : public base<class_b>, 
       public class_a 
{ 
    using base<class_b>::f; 
}; 

int main() 
{ 
    class_b b; 
    b.f(); 
    return 0; 
} 

Comeu và Intel C++ tuyên bố v11 tất cả là tốt, tuy nhiên GCC (4.4.1) và VC++ 2008 dường như phàn nàn (http://codepad.org/KQPDsqSp), ví dụ: :

g++ -pedantic -Wall -o test test.cpp 
test.cpp: In function ‘int main()’: 
test.cpp:5: error: ‘void base<T>::f() [with T = class_b]’ is inaccessible 
test.cpp:14: error: within this context 

Tôi tin rằng mã được tạo thành tốt, tuy nhiên tôi có thể sai, tôi hy vọng ai đó từ cộng đồng SO C++ có thể cung cấp một số thông tin chi tiết về vấn đề này.

Lưu ý: Thêm "công khai" trước chỉ thị sử dụng trong class_b, giải quyết vấn đề cho cả gcc và VS. Nên phần accessor của lớp trong đó chỉ thị sử dụng được áp dụng ghi đè chế độ dẫn xuất (public, private) của lớp cơ sở?

Nói tóm lại là thế này

  • Một lỗi biên dịch - nếu mà trình biên dịch GCC, VS hoặc Comeu vậy, Intel
  • Là mã trên cũng được hình thành?
  • Phần truy cập trong đó chỉ thị sử dụng được gọi là ghi đè chế độ dẫn xuất của cơ sở?

Trả lời

3

Bạn đang làm gì ở đây, đang giải quyết sự mơ hồ bằng cách nhập biểu tượng vào các không gian tên riêng riêng. Do đó nó là phương pháp shadowing và thay đổi tầm nhìn của nó thành riêng tư. Bạn không thể có hai chức năng với cùng một nguyên mẫu chính xác cả riêng và công cộng, do đó f bây giờ là riêng tư.

Ít nhất GCC tin rằng using should be able to change the visibility của một hàm.

Tham chiếu về âm đạo được tìm thấy trong GCC bug database, cho thấy rằng việc sử dụng trên thực tế không bị ảnh hưởng bởi phạm vi.

Quan trọng nhất, một câu trả lời trực tiếp (C++ Chuẩn '03 - 7.3.3/15)

Các bí danh được tạo ra bởi sử dụng-khai có khả năng tiếp cận thông thường cho một thành viên khai.

Do đó câu trả lời sẽ là:

  • đó là một lỗi trong Comeau
  • không, mã không cũng được hình thành, ít nhất là C++ 03-khôn ngoan (không thể tìm thấy bất cứ điều gì liên quan trong C++ 0x N3000)
  • có, bạn có thể thay đổi phạm vi truy cập
+0

Không có gì nằm trong không gian tên hoặc phạm vi riêng. và chỉ thị sử dụng không xem xét phần truy cập của lớp mà nó được gọi - tuy nhiên việc thêm công khai trước khi chỉ thị sử dụng giải quyết vấn đề. Tôi tin rằng trong trường hợp này gcc và VS có lỗi, bạn có nghĩ vậy không? –

+2

@darid, trong liên kết được cung cấp ở trên bạn sẽ thấy rằng ít nhất trong trường hợp của GCC nó đã được thay đổi theo cách nó bây giờ rõ ràng. –

+0

@ Kornel: thats một câu trả lời tuyệt vời, tôi muốn thêm Tôi đã thử nó với trình biên dịch C++ intel và nó thích nó như Comeau nào.Tôi tự hỏi nếu một vấn đề giao diện phân tích cú pháp của nó, intel và Comeau nhận được của họ từ EDG, nhưng cũng như MS cho VSC++, mà chỉ gây nhầm lẫn mọi thứ nhiều hơn nữa. –

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