我仍然被那些为了支持移动和转发而发明的规则弄糊涂了。有一件事我还不太确定:
转发引用是否只是rvalue引用(应用了引用折叠规则)?
如果它是一个rvalue引用,那么为什么函数:
template<typename T>
void func(T&&);
不仅接受rvalues,还接受lvalues?
在t
被替换之前,t&&
是一个rvalue引用(显然)。
在T
被替换之后(以及在引用折叠之后),T&
或者保持rvalue引用(如果T
不是引用),或者成为lvalue引用(如果T
是lvalue引用)。
我不确定这个答案是否会让你满意,但我可以指出标准的相关部分。简而言之,引用t&&
在“语法上”始终是rvalue引用,但有时它最终声明的类型是lvalue引用类型。
当这种情况作为模板参数推演的结果发生时,作为一个方便的速记,整个构造被称为“转发引用”。(这种情况需要引用折叠,但模板参数推演并不是引用折叠发生的唯一时间。)
现在来看看标准的措辞。首先,我们有[dcl.ref](例如p2、p6):
使用&
声明的引用类型称为lvalue引用,使用&
声明的引用类型称为rvalue引用。[...]
如果typedef-name(9.1.3,13.1)或decltype-specifier(9.1.7.2)表示对t
类型的引用tr
类型的tr
类型,则尝试创建类型“lvalue reference to cvtr
”将创建类型“lvalue reference tot
”,而尝试创建类型“rvalue reference to cvtr
”将创建类型“tr
”将创建类型“tr
”。[注:此规则称为引用折叠。-结尾注]
最后,模板参数推演的情况在[temp.defint.call]P3中处理:
转发引用是对cv-unqualified模板参数[...]的rvalue引用
换句话说,转发引用是rvalue引用,但它也接受lvalue引用。(请注意,标准的“转发引用”定义实际上并不要求推导模板参数,尽管这是您通常希望触发引用折叠行为的主要方式。)
假设一个函数有两个重载 然后在另一个函数的主体中 过载<代码>f(T 这让我非常惊讶。一个带有签名
我一直在切换模板工厂函数来使用(和理解)d::f支持右值和移动语义学。我常用的模板类样板工厂函数总是将参数标记为const: 按预期编译。最初,我将MakeMyPair转换为以const形式传递参数,但这不会使用XCode 4.6在我的Mac上编译: 没有用于调用“MakeMyPair\U Forward”候选函数的匹配函数[具有T=int,U=bool]不可行:没有从“int”到“const i
问题内容: 据我所知,使用旧的JMM来实现懒惰单调的DCL(双重检查锁定)技巧被打破了,但是我坚信它已被新的JMM和volatile字段所修复… 但是,在这篇不错的文章中,这显然已经足够新,足以引用DCL中的新旧JMM和volatile字段,表明它仍然坏了… 我在这里到那里读到它是固定的,然后我发现了这一点……有人可以最后说它是否损坏了? 我的理解是,通过波动性地在关系发生之前保证发生的先兆并有效
问题内容: 是否仍然有效?我想知道本书中描述的思想,概念和实现是否仍与最新的Java版本兼容。 我问是因为最新版本是2006年完成的。 问题答案: 是的,在我看来仍然有效。从6到7的变化不大。Fork- join是一项新功能,非常适合分治法式的问题。但是本书中所有现有的东西,例如同步,易失性,servlet,仍然非常有效。
我有一个关于转发推荐信的具体问题。(我认为)我理解R值引用和,但理解转发引用有困难: 是,这很好。如果是类型,为什么它打印“lvalue”,而我们需要?我的意思是,从到的转换在哪里?
问题内容: PHP中是否有一种方法可以确定给定变量是否是对另一个变量的引用和/或被另一个变量引用?考虑到php.net上的注释,设置可能意味着“ $ a和$ b在这里完全相等。 我可能会无法分开检测“对……的引用”和“对……的引用” 。$ a并不指向$ b或反之亦然。$ a和$ b指向同一位置。 ” 如果无法确定给定变量是否是引用/引用,是否存在一种通用方法来确定两个变量是否是彼此引用?再次,对p