我最近一直在做一个项目,我决定将ReSharper C ++安装到Visual Studio中。当它分析我的代码时,它会吐出一堆新的警告(显然我的编码习惯很糟糕......)。我花了一段时间才弄明白的其中一个是Binding r-value to l-value reference is non-standard Microsoft C++ extension
。我用以下代码重新创建了警告:
Type foo(Type t1, Type t2) {
return Type(t1.value & t2.value);
}
表达式t1.value & t2.value
触发警告。我理解警告的第二部分,这意味着我的代码只是由于Microsoft扩展而编译,而其他编译器会拒绝编译它。我正在使用重载运算符,它返回一个对象(称为Datum
),Type
将其作为构造函数参数,作为引用(Type::Type(Datum& dat)
)。
通过一些游戏,我设法通过重构代码来消除警告:
Type bar(Type t1, Type t2) {
Datum datum = t1.value & t2.value;
return Type(datum);
}
据我了解,这在功能上等同于生成警告的代码。我真正想知道的是这里是否有一些我应该注意的事情,因为我很困惑为什么一个函数会抱怨而另一个函数没有。
我想我已经明白了。我已经把问题输出了,所以我要用我发现的内容发布它,以供其他人参考。我没有足够的知识进入细节,所以如果不满意,请随意扩展或更正我的答案:)
答案 0 :(得分:6)
这是删除警告的一种方法:变量是左值,因此可以直接绑定到狡猾的构造函数的引用参数,而表达式结果是 rvalue 不能。
更好的解决方案是修复构造函数以通过值或常量引用获取其参数:
Type(Datum dat) // value
Type(Datum const & dat) // constant reference
现在您可以将参数指定为左值或右值。
答案 1 :(得分:0)
从我所看到的,我得到这种行为的原因是因为Type
构造函数将引用带到Datum
对象,而不是通过值传递它。这会在Type foo(Type, Type)
中引发警告,因为编译器不喜欢引用表达式,这可能是由于表达式求值的语义造成的。
再次,请随意详细说明或更正我的发现,因为这只是我的实验和推断的结果。