2015-04-17 13 views
18

Hier ist ein sehr einfaches C++ 11-Programm, das die Verwendung des final Keyword-Tests aus einer Klasse zu verhindern subclassed werden:Warum darf dieser Code unter Visual Studio 2013 kompiliert werden?

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

private: 
    T t; 
}; 

class Derived : public Base<int> {}; 

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

Wenn ich versuche, das obige Programm unter Mac zu kompilieren   OS X   (Clang), erhalte ich die erwarteten Fehlermeldungen:

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 

Allerdings, wenn ich den gleichen Code unter Windows mit Visual Studio 2013 zu kompilieren, kompiliert es ohne Fehler. Wenn ich die Base Klasse nicht vorschreibt, erkennt Visual Studio jedoch das Schlüsselwort final und gibt einen Fehler aus.

Ist das ein Fehler in Visual Studio 2013 oder fehlt mir etwas Nuance darüber, wie das final-Schlüsselwort in Verbindung mit Vorlagenklassen funktionieren soll/wird?

Antwort

18

Es ist in der Tat ein Fehler.

N4296, [Klasse]/p3:

Wenn eine Klasse mit den Klasse-virt-Spezifiziererfinal markiert und es scheint, als Basistyp-Spezifizierer in einer Basis -clause (Abschnitt 10), das Programm ist schlecht gebildet.

-5

Ich kenne nicht alle Interna der Kombination, aber IMHO beide Compiler sind "korrekt". MSVC erkennt, dass die Vorlagenklasse endgültig ist und Sie nicht daraus abgeleitet werden. Sie verwenden die Template-Klasse, um die Klasse Base < int> zu definieren, die nicht mehr final ist.

IMHO unterschiedliche Interpretation der Compiler.

+1

'klasse Abgeleitet: öffentliche Basis ' macht es sehr offensichtlich, dass 'Abgeleitet' tatsächlich abgeleitet wird; Es gibt keinen Interpretationsspielraum (zum Glück). – molbdnilo

+2

_ "beide Compiler sind 'korrekt' ... unterschiedliche Interpretation der Compiler" _ [Dies ist wohldefiniertes Verhalten] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014) /n4296.pdf) und [Visual Studio ist falsch] (http://stackoverflow.com/a/29710305/1350209). –

+0

yeah right ... wenn die Template-Klasse Base instanziiert wird, bekommt sie das "final". Meine fehlende Lücke ... – relascope

13

Ich glaube, es ist ein Fehler in VS 2013

Für das, was es wert ist, der Compiler aus der VS 2015 CTP tut, was (glaube ich) Sie wahrscheinlich erwarten würde:

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