C++版 寿限無、寿限無...

とある長ったらしいメンバ関数`D::mf()`の定義：

```C++
struct D : B {
  [[deprecated("wtf")]] virtual inline auto mf() const volatile && noexcept(noexcept(h)) [[using std:]] -> unsigned long long int override final
    { return 42; }
};
```

キーワードを適当に並べたかのようですが、これはC++言語仕様に則った"合法"な構文です。下記ソースコードはC++17準拠コンパイラにより正常にコンパイルされ、実行時エラーなく正常終了します。

```C++
#include <cassert>

void h();
struct B {
  virtual unsigned long long int mf() const volatile && = 0;
};

/* (前述のクラスD定義はココ) */

int main() {
  assert(D{}.mf() == 42);
}
```

# 簡易解説

あまりに横長で見づらいため、構成要素別にコードを改行して説明用のラベルを振ります：

```C++
/* (1)*/ [[deprecated("wtf")]]
/* (2)*/ virtual inline
/* (3)*/ auto
/* (4)*/ mf()
/* (5)*/ const volatile
/* (6)*/ &&
/* (7)*/ noexcept(noexcept(h))
/* (8)*/ [[using std:]]
/* (9)*/ -> unsigned long long int
/*(10)*/ override final
```

- (1) メンバ関数に対する [属性指定(_attribute-specifier_)][attribute] です。[`deperecated`属性][attr-deprecated]は対象が非推奨であることを表します。このメンバ関数を呼出すソースコード箇所では、C++コンパイラはメッセージ`"wtf"`を警告に出力します。あくまで警告ですからコンパイル自体は通ります。
- (2) メンバ関数が 仮想関数(`virtual`) であり、かつ インライン関数(`inline`) であると宣言します。C++プログラマの直感に反して、両キーワードは同時指定が可能です。[^virtual-inline]
- (3) メンバ関数の戻り値型を後置することを宣言します。(9)とペアです。
- (4) メンバ関数の名前です。`mf`。
- (5) メンバ関数に対する CV修飾(_cv-qualifier_) です。このメンバ関数定義中では`this`の型は`const volatile D *`になります。
- (6) メンバ関数に対する [参照修飾(_ref-qualifier_)][ref-qualifier] です。このメンバ関数は右辺値(rvalue)に対して呼び出されます。
- (7) メンバ関数に対する noexcept指定(_noexcept-specifier_) です。外側の[`noexcept`][noexcept]は指定子(specifier)であり、内側の[`noexcept`][noexcept]は演算子(opearator)です。
- (8) メンバ関数の型に対する 属性指定(_attribute-specifier_) です。`using`は属性指定中(`[[ ]]`)でのみ[名前空間を取り込む][using-attrns]ことを指示します。C++17では名前空間`std`配下に属性は定義されないので、具体的な属性は何も指定しません（できません）。
- (9) メンバ関数の [後置戻り値型(_trailing-return-type_)][trailing_return_type] を宣言します。[64bit符号無し整数型][longlong]です[^llu]。
- (10) 基底クラスの仮想関数をオーバーライドする([`override`][override-final])ものであり、かつ自身からの派生クラスではオーバーライドを許容しない([`final`][override-final])ことを宣言します。

# C++20強化版

```c++

template <auto... Ns>
struct D : B {
  [[deprecated("wtf")]] virtual inline 
  auto mf() const volatile &&
    noexcept(noexcept(h)) [[using std:]] -> unsigned long long int
      requires requires { (Ns * ...); }
        override final
    { return (Ns * ...); }
};
```

* 1個目の`requires`はメンバ関数に対する [requires節(_requires-clause_)][requires] です。続くrequires式が真値(`true`)に評価される場合に限って、クラステンプレートのメンバ関数が定義されます。
* 2個目の`requires`は [requires式(_requires-expression_)][requires] です。テンプレートパラメータに対する要件を定義します。ここでは式`(Ns * ...)`が有効であることを要求します。

[attribute]: https://cpprefjp.github.io/lang/cpp11/attributes.html
[attr-deprecated]: https://cpprefjp.github.io/lang/cpp14/deprecated_attr.html
[ref-qualifier]: https://cpprefjp.github.io/lang/cpp11/ref_qualifier_for_this.html
[noexcept]: https://cpprefjp.github.io/lang/cpp11/noexcept.html
[override-final]: https://cpprefjp.github.io/lang/cpp11/override_final.html
[trailing_return_type]: https://cpprefjp.github.io/lang/cpp11/trailing_return_types.html
[using-attrns]: https://cpprefjp.github.io/lang/cpp17/using_attribute_namespaces.html
[longlong]: https://cpprefjp.github.io/lang/cpp11/long_long_type.html
[requires]: https://cpprefjp.github.io/lang/cpp20/concepts.html

[^virtual-inline]: C++ FAQ, [Are "inline virtual" member functions ever actually "inlined"?](http://www.cs.technion.ac.il/users/yechiel/c++-faq/inline-virtuals.html)
[^llu]: 厳密には64bit幅 "以上の" 符号無し整数型。