ふと、こんなつぶやきを聞いた気がする。
struct foo { auto f()->int && { ... } }; って、int f() && か、int && f() のどっちに解釈されるの?
誰がつぶやいたのか覚えがないが、同時に、「プリプロセッサたんは俺の嫁」というつぶやきも聞いた気がする。不思議なことだ。一体誰がつぶやいたのだろう。それに、俺の嫁はUnified Function Sytanx(統一関数文法)たんに決まっている。New function declaration syntax(新関数宣言文法)たんでは、断じてない。
それ以降、つぶやきは聞こえなくなってしまった。おそらくは自力で問題を調べ、わざわざ答えをつぶやくまでもない、しごく簡単な疑問だということに気がついたのだろう。結論から言うと、
struct foo { auto f() ->int && ; } ;
この新しい関数宣言の記法を使ったコードは、従来の関数宣言の文法を使えば、
struct foo { int && f() ; } ;
このように書くことが出来る。一方、*thisへのref-qualiferを指定したければ、
struct foo { auto f() && -> int ; } ;
このようになる。理由は簡単明白だ。規格をちらと見ただけで、見逃しようもないほどはっきりと書いてある。
In a declaration T D where D has the form
D1 ( parameter-declaration-clause ) attribute-specifieropt cv-qualifier-seqopt ref-qualifieropt exception-specificationopt trailing-return-type
and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”, T shall be the single type-specifier auto.
つまり、順番がわかりやすいように、全部を使ってメンバ関数を長々と書くと、以下のようになる。
struct foo { auto // T はautoでなければならない。 f // 関数の名前 (void) // 引数リスト [[]] // attribute const volatile // cv-qualifier && // ref-qualifer throw() // exception specification -> int && // 戻り値の型 ; // expression-statementの終端記号 } ;
これを、従来の関数の文法と比べてみると、以下のようになる。
// 従来の文法 int && f(void) [[]] const volatile && throw() ; // 新文法 auto f(void) [[]] const volatile && throw() -> int && ;
ちなみに、Unified Function Syntaxが可決された暁には、autoが[]になる。
[] f() -> int ;
Unified Function Sytanxは、とても素晴らしいので、是非とも規格入りしてもらいたい。
No comments:
Post a Comment