C++11 has the new override
qualifier which can be applied to member functions to assert that they override a virtual function in the base class. C++11 also allows trailing return types so functions can be declared as auto f() -> return_type
. When I combine both these features, I don't know whether override
goes before or after the ->
.
For example, suppose we have the following base class:
struct Base { virtual auto f () const -> int = 0; };
The two possibilities for a derived class are:
struct Derived : public Base { virtual auto f () const override -> int { return 0; } // Compiles on g++ 4.7.1 };
or
struct Derived : public Base { virtual auto f () const -> int override { return 0; } // Compiles on clang++ 4.0 };
g++ 4.7.1 compiles the first version but fails on the second with
test.cpp:6:30: error: expected ';' at end of member declaration test.cpp:6:34: error: 'override' does not name a type
whereas clang++ 4.0 compiles the second one but fails on the first with
test.cpp:6:11: error: 'auto' return without trailing return type virtual auto f () const override -> int { return 0; } ^ test.cpp:6:3: error: only virtual member functions can be marked 'override' virtual auto f () const override -> int { return 0; } ^ ~~~~~~~~ test.cpp:6:35: error: expected ';' at end of declaration list virtual auto f () const override -> int { return 0; }
Which of these compilers is actually doing the right thing according to the standard?
Edit: As Kerrek SB notes, this is a bug in gcc (Bugzilla link).
The trailing return type feature removes a C++ limitation where the return type of a function template cannot be generalized if the return type depends on the types of the function arguments.
In C++14, you can just use auto as a return type.
According to the standard, 8.4.1, a declarator for a function includes the trailing-return-type, and a class function definition contains "declarator virt-specifier-seqopt". The second one, virt-specifier-seq, is one of final
or override
, so those come after the trailing return type. (I.e. Clang gets it right.)
like this:
class I { virtual auto Func() -> void = 0; }; class C : public I { auto Func() -> void override; };
It works in gcc since 4.8.1:
https://godbolt.org/z/TbTTwa
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With