【问题标题】:Binding r-value to l-value reference is non-standard Microsoft C++ extension将右值绑定到左值引用是非标准 Microsoft C++ 扩展
【发布时间】:2015-06-25 09:39:48
【问题描述】:

我最近一直在做一个项目,我决定将 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);
}

据我了解,这在功能上等同于生成警告的代码。我真正想知道的是这里是否有一些我应该注意的事情,因为我很困惑为什么一个函数会抱怨而一个函数不会抱怨。

我想我已经弄清楚了。我已经把问题打出来了,所以我将把我找到的内容一起发布,以供其他人参考。我真的没有足够的知识来详细介绍,所以如果不满意,请随时扩展或更正我的答案:)

【问题讨论】:

  • Type::value 应该是什么?它如何支持二进制& 运算符?
  • 很抱歉给您带来了困惑。 Type::valueDatum 类的一个对象,它包含一个字节数组。它类似于单个数据类型。当您应用二进制 & 运算符时,该运算符将应用于所有位,就像在整数上使用它一样。

标签: c++ resharper rvalue lvalue resharper-c++


【解决方案1】:

这是消除警告的一种方法:变量是一个左值,因此可以直接绑定到狡猾的构造函数的引用参数,而表达式结果是一个右值不能。

更好的解决方案是固定构造函数以通过值或常量引用获取其参数:

Type(Datum dat)         // value
Type(Datum const & dat) // constant reference

现在您可以将参数指定为 lvaluervalue

【讨论】:

    【解决方案2】:

    据我所知,出现这种行为的原因是 Type 构造函数将 reference 指向 Datum 对象,而不是按值传递它。这会在Type foo(Type, Type) 中引起警告,因为编译器不喜欢引用表达式,这可能是由于表达式求值的语义。

    再次,请随时详细说明或更正我的发现,因为这只是我的实验和推断的结果。

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 2014-10-31
      • 2011-02-14
      • 2014-05-18
      • 2017-04-13
      • 2013-08-24
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多