Using 'override' for a function that has been declared using 'typedef'

Viewed 1086

C++ 11 introduced the 'override' specifier for functions and I find it useful as it makes it explicit that a virtual function is being overridden. However, I can't seem to get it work for a function that has been declared using a typedef.

I understand that 'override' is not a keyword, has it got something to do with that?

The following code illustrates my point:

#include <iostream>

typedef char ReturnsChar();

class Basic
{
    public:
    virtual char get_a();
    virtual ReturnsChar get_z;
};

char Basic::get_a() { return 'a'; }
char Basic::get_z() { return 'z'; }

class Capitalized : public Basic
{
    public:
    // Can override explicitly if I use the normal definition
    char get_a() override;

    // Compiles if I use the typedef but not 'override'
    ReturnsChar get_z;

    // Will not compile, but would like to do this
    //ReturnsChar get_z override; 

};

char Capitalized::get_a() { return 'A'; }
char Capitalized::get_z() { return 'Z'; }

int main()
{
    Basic foo;
    Capitalized bar;

    std::cout << foo.get_a() << std::endl; // a
    std::cout << foo.get_z() << std::endl; // z
    std::cout << bar.get_a() << std::endl; // A
    std::cout << bar.get_z() << std::endl; // Z
}

I'm using GNU's g++ 8.2.0 and the error it gives me is

error: expected ';' at end of member declaration
ReturnsChar get_z override;
            ^~~~~
                      ;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
     ReturnsChar get_z override;
                       ^~~~~~~~
                       ctermid

EDIT: To address the comments, I understand this style is unclear. I am more interested about why this won't compile and what exactly 'override' does (especially because it is not a keyword). As an aside, I feel like typedef-ing functions might be clear in some cases, say:

void (*foo(int x, void (*f)(int)))(int);

That's hard to read, especially if comes up often. I can just typedef that as 'UpdateAddressFunction' and then mentally think of every function of that type as something that 'updates an address'.

1 Answers

I understand that 'override' is not a keyword, has it got something to do with that?

It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.

The relevant grammatical production for this is

[class.mem]

member-declarator:
  declarator virt-specifier-seqopt pure-specifieropt

This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:

[class.mem]p8:

A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).

In your case, the declaration is one of a virtual member function. I believe override should be accepted here.

Related