了解警告:将r值绑定到l值参考 [英] Understanding the warning: binding r-value to l-value reference

查看:76
本文介绍了了解警告:将r值绑定到l值参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过引用传递结构,因此不会被复制,但是Resharper在下面给出警告:

I want to pass a struct by reference so it won't be copied, but Resharper is giving the warning below:

struct sometype {
};

sometype foo() {
    sometype x;
    return x;
}

void bar() {
    sometype & a = foo();//Binding r-value to l-value reference is non-standard Microsoft C++ extension
    sometype && b = foo(); //ok
}

问题:

sometype&有什么问题? a = foo(); 吗?不是 foo()的左值和 a 的返回值也是左值?

What's wrong with sometype & a = foo(); ? isn't the return value from foo() an lvalue and a is also an lvalue?

sometype&& b = foo(); 实际上是右值引用?它会窃取 foo()的返回值并将 b 中的内容发送给析构函数吗?

Is sometype && b = foo(); actually rvalue reference? Does it "steal" the return value from foo() and send what was in b to the destructor?

还有另一种方式不发出此警告吗?

Is there another way to not have this warning?

推荐答案

引用一个临时对象。唯一合法的方法是:

You are taking a reference to a temporary object. The only legal way to do this is either :

const object& (const左值引用),或者

const object& (const l-value reference), or

对象& (可变r值引用)

这是(故意的)语言限制。

This is a (deliberate) language limitation.

进一步的讨论:

将临时任务分配给引用延长了临时对象的生存期,使其与引用的生存期匹配。因此,令许多初学者惊讶的是,这是合法的:

Assigning a temporary to a reference extends the lifetime of the temporary so that it matches the lifetime of the reference. Therefore, surprisingly to many beginners, this is legal:

{
  const string& s = foo();
  cout << s << endl;         // the temporary to which s refers is still alive
}
// but now it's destroyed

但是,对可变项进行可变引用通常是逻辑错误,因此在以下语言中是不允许的:

However, it would normally be a logic error to take a mutable reference to a temporary so this is disallowed in the language:

{
  string s& = foo();  // this is not possible
  s += "bar";         // therefore neither is this
  // the implication is that since you modified s, you probably want to
  // preserve it
}
// ... but now it's destroyed and you did nothing with it.

以下是更现实的原因,它可能是逻辑错误,给定:

here's a more realistic reason why it's probably a logic error, given:

string foo();         // function returning a string
void bar(string& s);  // this function is asserting that it intends to *modify*
                      // the string you sent it

// therefore:

bar(foo());           // makes no sense. bar is modifying a string that will be discarded.
                      // therefore assumed to be a logic error

您必须将上述内容替换为:

you would have to replace the above with:

  string s = foo();
  s += "bar";
  // do something here with s

做一些事情,请注意,捕获

Note that there is no overhead whatsoever for capturing the temporary in a named variable (l-value).

r值引用被设计为移动构造函数或移动赋值的主题。因此,它们是可变的是有意义的。

r-value references are designed to be the subject of a move-constructor or move-assignment. Therefore it makes sense that they are mutable. Their very nature implies that the object is transient.

因此,这是合法的:

string&& s = foo();    // extends lifetime as before
s += "bar";
baz(std::move(s));     // move the temporary into the baz function.

它可能会帮助您记住指定& 是您在断言您知道该变量是可变临时变量。

It might help you to remember that specifying && is you asserting that you know that the variable is a mutable temporary.

但是允许它的真正原因是这样会起作用:

But the real reason it's allowed is so that this will work:

string foo();   // function that returns a string
void bar(string&& s);  // function that takes ownership of s

bar(foo());  // get a string from foo and move it into bar

// or more verbosely:

string s = foo();
bar(move(s));

在c ++ 11之前,必须以下列方式之一写出bar: p>

prior to c++11, bar would have to have been written one of these ways:

void bar(string s);   // copy a string

// resulting in:

const string& s = foo();
bar(s);  // extra redundant copy made here

void bar(const string& s); // const l-value reference - we *may* copy it
// resulting in:

const string& s = foo();
bar(s);  // maybe an extra redundant copy made here, it's up to bar().

这篇关于了解警告:将r值绑定到l值参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆