Ответ 1
Это действительно ошибка.
N4296, [класс]/p3:
Если класс помечен спецификатором class-virt-t
final
и он появляется в качестве базового-спецификатора в базовом-разделе (раздел 10), программа плохо сформирована.
Вот очень простая программа на С++ 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
разрешено/ожидается для работы в сочетании с шаблонами?
Это действительно ошибка.
N4296, [класс]/p3:
Если класс помечен спецификатором class-virt-t
final
и он появляется в качестве базового-спецификатора в базовом-разделе (раздел 10), программа плохо сформирована.
Я считаю, что это ошибка в VS 2013.
Для чего это стоит, компилятор из VS 2015 CTP делает то, что (я думаю), вы, вероятно, ожидаете:
test.cpp(10): error C3246: 'Derived': cannot inherit from 'Base<int>' as it has been declared as 'final'
Я не знаю всех внутренних компонентов комбинации, но IMHO оба компилятора являются "правильными". MSVC видит, что класс шаблона является окончательным, и вы не получаете его. ИСПОЛЬЗУЙТЕ класс шаблона для определения класса Base <int> , который не является окончательным.
ИМХО различная интерпретация компиляторов.