据我所知,我不能声明对void
的右值引用
例如,以下代码格式不正确:
void f(void &&v) { }
从[20.2.6/1](函数模板declval)我们有declval
的声明:
template <class T>
add_rvalue_reference_t<T>
declval() noexcept;
因此,declval<void>
(我说)会在void &&
中产生,我猜测它与前一个例子中的格式不合理。
无论如何,以下最小的工作示例编译:
#include<utility>
int main() {
decltype(std::declval<void>())* ptr = nullptr;
}
请注意以下情况也是如此:
static_assert(std::is_same<decltype(std::declval<void>()), void>::value, "!");
我原本以为void&&
如前所述(或更好,我原以为它无法编译)。
实际上,它恰好是任何其他非参考类型的右值参考
举个例子:
static_assert(std::is_same<decltype(std::declval<int>()), int&&>::value, "!");
declval<void>
是否是有效表达式?代码是否合法?
为什么void
的行为与任何其他类型的行为不同? (因为如果代码是合法的,那么就不会起作用可能是一个答案。
如果合法,标准允许哪些内容?我找不到这个案子了 当然,标准说:
declval的模板参数T可能是不完整的类型。
无论如何,这里会导致一个不可接受的类型(void&&
)并且它会绕着它丢弃右值参考。
答案 0 :(得分:10)
add_rvalue_reference<T>
是可引用类型,则 T&&
仅会导致T
。因此,当T
为void
时,结果只有void
。这也是为什么你可以add_rvalue_reference<int&&>
并且在尝试构造对引用的引用时不会出错的原因。 (与左值参考相同。)