2015-04-17 22 views
18

Dưới đây là một chương trình rất đơn giản, C++ 11 mà kiểm tra ra việc sử dụng các từ khóa final để ngăn chặn một lớp khỏi bị subclassed:Tại sao mã này được phép biên dịch trong Visual Studio 2013?

template<class T> class Base final 
{ 
public: 
    Base() {} 

private: 
    T t; 
}; 

class Derived : public Base<int> {}; 

int main(int, char **) 
{ 
    Derived d; 
    return 0; 
} 

Nếu tôi cố gắng để biên dịch chương trình trên dưới Mac OS     X (Clang), tôi nhận được thông báo lỗi dự kiến:

jeremy-friesners-mac-pro-3:~ jaf$ g++ -std=c++11 ./temp.cpp 
./temp.cpp:10:28: error: base 'Base' is marked 'final' 
    class Derived : public Base<int> {}; 
        ^
./temp.cpp:1:29: note: 'Base' declared here 
    template<class T> class Base final 

Tuy nhiên, nếu tôi biên dịch mã cùng hệ điều hành Windows sử dụng Visual Studio 2013, nó biên dịch không có lỗi. Tuy nhiên, nếu tôi làm cho lớp Base không được tạo mẫu, Visual Studio sẽ nhận ra từ khóa final và phát ra lỗi.

Đây có phải là lỗi trong Visual Studio 2013 hoặc tôi thiếu một số sắc thái về cách từ khóa final được phép/dự kiến ​​hoạt động cùng với các lớp được tạo khuôn mẫu?

Trả lời

18

Nó thực sự là một lỗi.

N4296, [lớp]/p3:

Nếu một lớp được đánh dấu bằng các đẳng cấp virt-specifierfinal và nó xuất hiện như một cơ sở-type-specifier trong một cơ sở -clause (Điều 10), chương trình không đúng định dạng.

-5

Tôi không biết tất cả nội bộ của kết hợp, nhưng IMHO cả hai trình biên dịch đều là "đúng". MSVC thấy rằng lớp mẫu là cuối cùng, và bạn không xuất phát từ nó. Bạn sử dụng lớp mẫu để định nghĩa lớp cơ sở < int>, mà không phải là cuối cùng nữa.

IMHO giải thích khác nhau về trình biên dịch.

+1

'class Xuất phát: cơ sở công khai ' làm cho nó rất rõ ràng rằng 'Derived' thực sự là bắt nguồn; không có chỗ để giải thích (may mắn thay). – molbdnilo

+2

_ "cả hai trình biên dịch là 'chính xác' ... giải thích khác nhau của trình biên dịch" _ [Đây là hành vi được xác định rõ] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014 /n4296.pdf) và [Visual Studio là sai] (http://stackoverflow.com/a/29710305/1350209). –

+0

vâng phải ... khi instantiating mẫu lớp cơ sở , nó được "cuối cùng". Khoảng cách mất tích của tôi ... – relascope

13

Tôi tin rằng đó là một lỗi trong VS 2013.

Đối với những gì nó có giá trị, trình biên dịch từ VS 2015 CTP làm những gì (tôi nghĩ), bạn có thể mong đợi:

test.cpp(10): error C3246: 'Derived': cannot inherit from 'Base<int>' as it has been declared as 'final' 
Các vấn đề liên quan