2015-04-17 2 views
18

Вот очень простой C++ 11 программа, которая проверяет вне использования final ключевого слова, чтобы предотвратить класс от того подклассов:Почему этот код разрешен для компиляции в 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; 
} 

Если я пытаюсь скомпилировать выше программы под Mac OS     X (Clang), я получаю ожидаемые сообщения об ошибках:

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 

Однако, если я компилирую тот же код под Windows, с помощью Visual Studio 2013, он компилируется без ошибок. Однако, если класс Base не templated, Visual Studio распознает ключевое слово final и испускает ошибку.

Является ли это ошибкой в ​​Visual Studio 2013, или мне не хватает некоторого нюанса о том, как ключевое слово final разрешено/ожидается для работы в сочетании с шаблонами?

ответ

18

It действительно является ошибкой.

N4296, [класс]/р3:

Если класс отмечен класс вирт-спецификаторfinal и он выступает в качестве базового типа спецификатора в базе -clause (пункт 10), программа плохо сформирована.

-5

Я не знаю всех внутренних компонентов комбинации, но IMHO оба компилятора являются «правильными». MSVC видит, что класс шаблона является окончательным, и вы не получаете его. Вы ИСПОЛЬЗУЕТ класс шаблона для определения класса Base < int>, который уже не является окончательным.

IMHO различная интерпретация компиляторов.

+1

'class Производный: общедоступный Base ' делает очень очевидным, что 'Derived' действительно получен; нет места для интерпретации (к счастью). – molbdnilo

+2

_ "оба компилятора являются« правильными »... различной интерпретацией компиляторов» _ [Это четко определенное поведение] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014 /n4296.pdf) и [Visual Studio ошибочно] (http://stackoverflow.com/a/29710305/1350209). –

+0

Да, правильно ... при создании шаблона класса Base , он получает «окончательный». Мой недостающий пробел ... – relascope

13

Я считаю, что это ошибка в VS 2013.

Для чего это стоит, компилятор от VS 2015 CTP делает то, что (я думаю), вы, вероятно, ожидать:

test.cpp(10): error C3246: 'Derived': cannot inherit from 'Base<int>' as it has been declared as 'final' 
Смежные вопросы