Порядок переопределения и noexcept в стандарте

требуется ли порядок переопределения и noexcept стандартом?

class Base
{
public:
  virtual void foo() {}
};

class Derived : public Base
{
public:
  // virtual void foo() override {} // Ok
  // virtual void foo() noexcept {} // Ok
  // virtual void foo() noexcept override {} // Ok
  virtual void foo() override noexcept {} // Error
};

int main() {}

Я использую gcc 4.7.2.

3 ответов


На самом деле, да, это так, его просто трудно выяснить, так как его немного разбросано. Приложение A (резюме грамматики) имеет некоторую помощь здесь. Давайте попробуем найти конкретные биты:

declarator:
    ptr-declarator
    noptr-declarator parameters-and-qualifiers trailing-return-type

parameters-and-qualifiers:
    ( parameter-declaration-clause ) attribute-specifier-seqopt cv-qualifier-seqopt
    ref-qualifieropt exception-specificationot

exception-specification:
    dynamic-exception-specification
    noexcept-specification

noexcept-specification:
    noexcept ( constant-expression )
    noexcept

а затем позже для переопределения

member-declarator:
    declarator virt-specifier-seqopt pure-specifieropt
    declarator brace-or-equal-initializeropt
    identifieropt attribute-specifier-seqopt: constant-expression

virt-specifier-seq:
    virt-specifier
    virt-specifier-seq virt-specifier

virt-specifier:
    override
    final

таким образом, Декларатор-это то, что содержит ключевое слово noexcept, но в члене-деклараторе спецификатор virt появляется после Декларатора.


В 8.3.5 [dcl.ПКТ] мы видим:

D1 (параметр-объявление-предложение ) cv-квалификатор-seq opt ref-квалификатор opt exception-спецификация opt атрибут-спецификатор-seq opt

...и в 9.2 [класс.мэм] мы видим:

Декларатор virt-спецификатор-seq opt pure-спецификатор opt

в ней говорится, что override и final должны прийти после noexcept.


выдержки из [грам.decl] / A. 7, акцент мой

объявления:
   ptr-Декларатор
   noptr-деклараторные параметры и квалификаторы trailing-return-type

ptr-Декларатор:
   noptr-Декларатор
   ptr-оператор ptr-Декларатор

noptr-Декларатор:
Декларатор-id атрибут-спецификатор-сл opt
noptr-Декларатор параметры-и-квалификаторы
noptr-Декларатор [ константа-выражение opt] атрибут-спецификатор-seq opt
   ( ПТР-Декларатор )

параметры-и-квалификаторов:
( параметр-объявление-предложение ) атрибут-спецификатор-seq opt cv-квалификатор-seq opt
ref-квалификатор optисключение-спецификация opt

[грам.class] / A. 8, акцент мой

член-Декларатор:
Декларатор virt-спецификатор-seq opt pure-specifier opt
   Декларатор brace-or-equal-initializer opt
   идентификатор opt атрибут-спецификатор-seq opt
: константное-выражение

virt-спецификатор-seq:
virt-спецификатор
   virt-спецификатор-seq virt-спецификатор

virt-спецификатор:
override
   final

то есть исключение-спецификация является частью Декларатор, который предшествует virt-спецификатор на член-Декларатор.