【发布时间】:2013-03-13 11:03:22
【问题描述】:
我用 GCC、Clang、ICC 和 VS 测试了以下代码:
void f() {}
void g(void (&&)()) { }
int main() {
g(f);
}
正如我们所见,g 采用右值引用,但 f 是左值,通常,右值引用不能绑定到左值。这正是 ICC 抱怨的原因:
error: an rvalue reference cannot be bound to an lvalue
VS 也会报错,但还有一个原因:
error C2664: 'void h(void (__cdecl &&)(void))' : cannot convert parameter 1 from 'void (__cdecl *)(void)' to 'void (__cdecl &&)(void)'
这表明 VS 会立即执行函数到指针的转换,而不是直接将引用绑定到 f。值得一提的是,如果我将g(f) 替换为g(&f),那么四个编译器会产生同样的错误。
最后,GCC 和 Clang 接受了代码,我相信他们是正确的。我的推理是基于 8.5.3/5
对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化为
——如果引用是左值引用 [...]
— 否则,[...] 引用应为右值引用。
- 如果初始化表达式是一个 [...] 函数左值 [...]
然后引用绑定到初始化表达式的值 [...]
我的解释是否正确(即 Clang 和 GCC 因给定原因而合规)?
【问题讨论】:
标签: c++ function c++11 language-lawyer rvalue-reference