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

Вот очень простая программа на C ++ 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 (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 без шаблона, Visual Studio распознает ключевое слово final и выдаст ошибку.

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


person Jeremy Friesner    schedule 17.04.2015    source источник


Ответы (3)


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

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

Если класс отмечен с помощью спецификатора-виртуального-класса final и отображается как спецификатор-базового типа в базовом предложении ( Пункт 10), программа составлена ​​некорректно.

person 0x499602D2    schedule 17.04.2015

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

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

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

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

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

person relascope    schedule 17.04.2015
comment
class Derived : public Base<int> делает очень очевидным, что Derived действительно является производным; нет места для интерпретации (к счастью). - person molbdnilo; 18.04.2015
comment
оба компилятора "правильные" ... разные интерпретации компиляторов Это четко определенное поведение и Visual Studio неверно. - person Cole Johnson; 18.04.2015
comment
да, верно ... при создании экземпляра класса шаблона Base ‹int› он получает финал. Мой недостающий пробел ... - person relascope; 05.05.2015