gpt4 book ai didi

c++ - 了解警告 : binding r-value to l-value reference

转载 作者:可可西里 更新时间:2023-11-01 17:25:10 25 4
gpt4 key购买 nike

我想通过引用传递一个结构,这样它就不会被复制,但 Resharper 发出以下警告:

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 不是左值吗?

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

是否有其他方法可以避免此警告?

最佳答案

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

const 对象&(const 左值引用),或者

object&&(可变右值引用)

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

进一步讨论:

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

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

但是,对临时对象进行可变引用通常是一个逻辑错误,因此这在语言中是不允许的:

{
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.

这里有一个更现实的原因,为什么它可能是一个逻辑错误,给出:

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

您必须将上面的内容替换为:

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

请注意,在命名变量(左值)中捕获临时变量没有任何开销。

r 值引用被设计为移动构造函数或移动赋值的主题。因此,它们是可变的是有道理的。它们的本质意味着对象是 transient 的。

因此,这是合法的:

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

这可能会帮助您记住,指定 && 是您断言您知道该变量是一个可变的临时变量。

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

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 必须以下列方式之一编写:

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().

关于c++ - 了解警告 : binding r-value to l-value reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34240794/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com