Подтвердить что ты не робот

Где находится квалификатор 'override' с возвращаемыми типами возврата?

С++ 11 имеет новый override квалификатор, который может применяться к функциям-членам, чтобы утверждать, что они переопределяют виртуальную функцию в базовом классе. С++ 11 также позволяет возвращать возвращаемые типы, поэтому функции могут быть объявлены как auto f() -> return_type. Когда я совмещаю обе эти функции, я не знаю, идет ли override до или после ->.

Например, предположим, что у нас есть следующий базовый класс:

struct Base {
    virtual auto f () const -> int = 0;
};

Две возможности для производного класса:

struct Derived : public Base {
    virtual auto f () const override -> int { return 0; } // Compiles on g++ 4.7.1
};

или

struct Derived : public Base {
    virtual auto f () const -> int override { return 0; } // Compiles on clang++ 4.0
};

g++ 4.7.1 компилирует первую версию, но не выполняет вторую с помощью

test.cpp:6:30: error: expected ';' at end of member declaration
test.cpp:6:34: error: 'override' does not name a type

тогда как clang++ 4.0 компилирует второй, но с первого раза не работает с

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; }

Какой из этих компиляторов действительно делает правильную вещь в соответствии со стандартом?

Изменить: Как отмечает Kerrek SB, это ошибка в gcc (ссылка Bugzilla).

4b9b3361

Ответ 1

В соответствии со стандартом, 8.4.1, декларатор для функции включает в себя тип trailing-return-type, а определение функции класса содержит "declarator virt-specifier-seq opt". Второй, virt-specifier-seq, является одним из final или override, поэтому они появляются после возвращаемого возвращаемого типа. (I.e. Clang понимает это правильно.)