Подтвердить что ты не робот

Почему этот код разрешен для компиляции в Visual Studio 2013?

Вот очень простая программа на С++ 11, которая проверяет использование ключевого слова final для предотвращения подкласса класса:

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 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 разрешено/ожидается для работы в сочетании с шаблонами?

4b9b3361

Ответ 1

Это действительно ошибка.

N4296, [класс]/p3:

Если класс помечен спецификатором class-virt-t final и он появляется в качестве базового-спецификатора в базовом-разделе (раздел 10), программа плохо сформирована.

Ответ 2

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

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

test.cpp(10): error C3246: 'Derived': cannot inherit from 'Base<int>' as it has been declared as 'final'

Ответ 3

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

ИМХО различная интерпретация компиляторов.