前几天进行一些模板元编程时遇到了奇怪的事情。基本上可以归结为这个断言没有(正如我期望的那样)通过。
static_assert(std::is_same_v<void(), std::remove_reference_t<void()&>>);
起初我以为我在定义函数引用时犯了语法错误,但是这个断言通过了,表明事实并非如此。
static_assert(std::is_same_v<void()&, void()&>);
我也尝试自己实现remove_reference
,从cppreference复制源,但这也不起作用。这是怎么回事?
答案 0 :(得分:41)
欢迎来到令人讨厌的函数类型的世界。
void() &
不是对void()
的引用。拼写方式为void(&)()
(如果您remove_reference_t
,您会得到void()
的拼写方式-即remove_reference_t
确实对函数的引用(如果您提供的内容实际上是对函数类型的引用)。
void() &
实际指的是剥离类后具有引用资格的成员函数的类型。那就是:
struct C {
void f() &;
};
&C::f
的类型为void (C::*)() &
。但是对于某个类型T C::*
,指向成员的所有指针都可以写成T
,在这种情况下,类型T
将是void() &
。
另请参阅P0172。
答案 1 :(得分:13)
您拥有的类型不是对函数的引用,而是对带有reference qualifier的函数的引用。
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(&)()>>);