[英]Can an rvalue reference bind to a function?
我用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是否符合给定的原因)?
我的解释是否正确[...]?
是。
由于您引用的标准段落,您的解释是正确的。 关于参考约束的第13.3.3.1.4 / 3段进一步确认:
除了隐式对象参数(参见13.3.1)之外,如果需要将除非对非易失性const类型的引用之外的左值引用绑定到右值或将左值引用绑定到左值,则无法形成标准转换序列除了函数左值 。 [...]
第13.3.3.2/3段包含进一步(间接)确认:
[...]标准转换序列S1是比标准转换序列S2更好的转换序列
- [...]
- S1和S2是引用绑定(8.5.3),S1将左值引用绑定到函数左值,S2将右值引用绑定到函数左值 。 [ 例如 :
int f(void(&)()); // #1 int f(void(&&)()); // #2 void g(); int i1 = f(g); // calls #1
- 结束例子 ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.