34

C ++ 11には、overrideメンバー関数に適用して、基本クラスの仮想関数をオーバーライドすることを表明できる新しい修飾子があります。C ++ 11では、末尾の戻り型も使用できるため、関数をとして宣言できますauto f() -> return_typeoverrideこれらの両方の機能を組み合わせると、の前に行くのか後になるのかわかりません->

たとえば、次の基本クラスがあるとします。

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

派生クラスの2つの可能性は次のとおりです。

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は最初のバージョンをコンパイルしますが、2番目のバージョンでは失敗します。

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は2番目のものをコンパイルしますが、最初のものでは失敗します。

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リンク)のバグです。

4

2 に答える 2

27

標準8.4.1によると、関数の宣言子には末尾のreturn-typeが含まれ、クラス関数の定義には「declaratorvirt-specifier-seqopt 」が含まれます。2番目のvirt-specifier-seqは、またはのfinalいずれかoverrideであるため、これらは末尾のリターンタイプの後にあります。(つまり、Clangはそれを正しく理解します。)

于 2012-10-07T17:22:16.033 に答える
1

このような:

class I
{
    virtual auto Func() -> void = 0;
};

class C : public I
{
    auto Func() -> void override;
};

4.8.1以降はgccで動作します:
https ://godbolt.org/z/TbTTwa

于 2019-03-15T08:59:49.257 に答える