Roshan Shariff
Roshan Shariff

Reputation: 558

Where does the 'override' qualifier go with trailing return types?

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).

Upvotes: 38

Views: 4915

Answers (2)

v.oddou
v.oddou

Reputation: 6775

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

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477100

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.)

Upvotes: 30

Related Questions