先日、テンプレートのメタプログラミングを行っているときに、奇妙なことに遭遇しました。それは基本的にこの主張に帰着します(私が期待する通り)通過しません。
static_assert(std::is_same_v<void(), std::remove_reference_t<void()&>>);
最初は、関数参照を定義する構文上の間違いを犯していると思っていましたが、このアサーションは成功し、そうではないことがわかりました。
static_assert(std::is_same_v<void()&, void()&>);
私も実装してみましたremove_reference
私自身、cppreferenceからソースをコピーしましたが、それも機能しませんでした。ここで何が起こっているのですか?
Abominable Function Typesの世界へようこそ。
void() &
はvoid()
への参照ではありません。 void(&)()
(_remove_reference_t
_の場合、void()
-_remove_reference_t
_が返されます。 )does提供するものが実際に関数型への参照である場合、関数への参照で機能します。
void() &
が実際に参照するのは、クラスを削除した後の参照修飾メンバー関数のタイプです。あれは:
_struct C {
void f() &;
};
_
_&C::f
_の型はvoid (C::*)() &
です。しかし、メンバーへのすべてのポインターは、一部の型T
の_T C::*
_として記述できます。この場合、型T
はvoid() &
になります。
P0172 も参照してください。
あなたが持っている型は関数への参照ではなく、 参照修飾子 を持つ関数です。
static_assert(std::is_same_v<void()&, void()&>);
static_assert(!std::is_same_v<void()&, void(&)()>);
static_assert(std::is_same_v<void(&)(), void(&)()>);
static_assert(std::is_same_v<void(), std::remove_reference_t<void(&)()>>);