プログラミング言語C++に「関数型(function type)の右辺値(rvalue)」は存在しない。関数型をもつ式の value category は常に左辺値(lvalue)となる。だから何?
int v; struct S s; void f(); std::move(v); // xvalue std::move(s); // xvalue std::move(f); // lvalue static_cast<void(&)()>(f); // lvalue static_cast<void(&&)()>(f); // lvalue static_cast<void(*)()>(f); // prvalue(関数ポインタ型)
void g(void(&)()); // #1 void g(void(&&)()); // #2 g(f); // #1を呼び出す g(std::move(f)); // #1を呼び出す
別途 Function-to-pointer 変換によって、関数型の lvalue は関数ポインタ型の prvalue へと変換されうる。*1
C++17 7/p6, 8.2.2/p11 より引用(下線部は強調)。*2
The effect of any implicit conversion is the same as performing the corresponding declaration and initialization and then using the temporary variable as the result of the conversion. The result is an lvalue if
T
is an lvalue reference type or an rvalue reference to function type (11.3.2), an xvalue ifT
is an rvalue reference to object type, and a prvalue otherwise. The expression e is used as a glvalue if and only if the initialization uses it as a glvalue.
A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.
C++11に右辺値参照が追加されたとき、新しい概念の導入による複雑化を避けるため特別扱いされた。(PDF)N3055 Background より一部引用。
In addition, rvalue references (like traditional lvalue references) can be bound to functions. Treating an rvalue reference return value as an rvalue, however, introduces the novel concept of a function rvalue into the language. There was previously no such idea -- a function lvalue used in an rvalue context becomes a pointer-to-function rvalue, not a function rvalue -- so the current draft Standard does not describe how such rvalues are to be treated. In particular, function calls and conversions to function pointers are specified in terms of function lvalues, so most plausible uses of rvalue references to functions are undefined in the current wording.
関連URL