【发布时间】:2017-01-09 21:31:12
【问题描述】:
据我所知,我无法声明对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&&) 并且它可以解决它丢弃右值引用。
【问题讨论】:
标签: c++ c++11 language-lawyer void decltype