2016-10-05 16 views
19

Các mã sau biên dịch và chạy, và không có cảnh báo được phát ra bởi một trong hai gcc hoặc kêu vang:Tôi có thể mất "constness" trong kiểu trả về của hàm ảo ghi đè không?

#include <iostream> 

struct Base { 
    virtual ~Base() = default; 
    virtual std::string const& get() = 0; 
}; 

struct Derived: Base { 
    virtual std::string& get() override { return m; } 
    std::string m; 
}; 

int main() 
{ 
    Derived d; 
    d.get() = "Hello, World"; 

    Base& b = d; 
    std::cout << b.get() << "\n"; 
} 

std::string& hiệp biến với std::string const& sau đó?

+0

có ý nghĩa, vì bạn chỉ có thể áp dụng lại độ chói cho người gọi nếu cần. Tất nhiên bạn không thể tự động lấy nó trở lại, nên ngược lại sẽ không đúng. – xaxxon

+0

@xaxxon: Vâng, tôi đã thực sự ngạc nhiên khi nó hoạt động (không bao giờ nghĩ về nó!) ... đặc biệt là vì CLion tiếc là đã báo lỗi ở đó. Tôi đưa ra một lỗi trên tracker của họ cho việc này. –

+1

Thú vị, tôi thấy nó cũng đã được sửa trong DR1250 để cho phép các loại không hoàn chỉnh: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1250 – marcinj

Trả lời

18

này được quy định tại class.virtual, trong dự thảo mới nhất (n4606) chúng ta thấy:

§10.3 7/ Kiểu trả về của một hàm trọng phải giống với kiểu trả về của hàm bị ghi đè hoặc covariant với các lớp của hàm. Nếu một hàm D::f ghi đè một chức năng B::f, các loại trở các chức năng là hiệp biến nếu họ đáp ứng các tiêu chí sau:

  • cả hai đều là con trỏ đến các lớp học, cả hai đều là tài liệu tham khảo giá trị trái đến các lớp học, hoặc cả hai đều là tài liệu tham khảo rvalue để lớp
  • lớp trong kiểu trả về của B::f là lớp tương tự như các lớp trong kiểu trả về của D::f, hoặc là một lớp cơ sở trực tiếp hoặc gián tiếp rõ ràng và dễ tiếp cận của lớp trong kiểu trả về của D::f
  • cả hai con trỏ hoặc tham chiếu có cùng trình độ cv và loại lớp trong kiểu trả về là D::f có cùng trình độ cv bằng hoặc ít hơn cv-qualification so với loại lớp trong kiểu trả về là B::f.

Cụ thể, các địa chỉ điểm cuối cùng chính là trường hợp ở đây: đó là chấp nhận được đối với một loại trọng để mất const và/hoặc volatile vòng loại (nó có thể không, tuy nhiên, đạt được chúng).


Lưu ý: như đã đề cập bởi @george trên, khoản 8/sử dụng để ngăn chặn điều này làm việc với các loại lớp học đầy đủ, nhưng đây là since fixed.

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