有什么方法可以将rvalue/temp对象传递给需要非成本引用的函数?

non*_*ot1 3 c++ parameters lvalue rvalue-reference c++11

我知道c ++只允许rvalues或temp对象绑定到const-references.(或接近那个 ...)

例如,假设我有函数doStuff(SomeValue & input)
SomeValue getNiceValue()定义:

/* These do not work */
app->doStuff(SomeValue("value1"));
app->doStuff(getNiceValue());

/* These all work, but seem awkward enough that they must be wrong. :) */

app->doStuff(*(new SomeValue("value2")));

SomeValue tmp = SomeValue("value3");
app->doStuff(tmp);

SomeValue tmp2 = getNiceValue();
app->doStuff(tmp2);
Run Code Online (Sandbox Code Playgroud)

那么,三个问题:

  1. 因为我无法自由更改doStuff()或的签名getNiceValue(),这是否意味着我必须总是使用某种"名称"(即使多余的)来传递给我的任何东西doStuff

  2. 假设,如果我可以更改功能签名,这种事情是否有共同的模式?

  3. 新的C++ 11标准是否会改变一切?C++ 11有更好的方法吗?

谢谢

AnT*_*AnT 6

在这种情况下,一个显而易见的问题是为什么将doStuff其参数声明为非const引用.如果它确实试图修改引用的对象,那么将函数签名更改为const引用不是一个选项(至少不是它本身).

无论如何,"rvalue-ness"是生成临时对象的表达式的属性,而不是临时对象本身的属性.临时对象本身可以很容易地成为左值,但是你将它视为右值,因为产生它的表达式是一个右值表达式.

您可以通过在您的班级中引入"右值到左值转换器"方法来解决它.比如,例如

class SomeValue {
public:
  SomeValue &get_lvalue() { return *this; }
  ...
};
Run Code Online (Sandbox Code Playgroud)

现在你可以将非const引用绑定到temporaries了

app->doStuff(SomeValue("value1").get_lvalue());
app->doStuff(getNiceValue().get_lvalue());
Run Code Online (Sandbox Code Playgroud)

不可否认,它看起来并不优雅,但它可能被视为一件好事,因为它会阻止你无意中做出类似的事情.当然,您有责任记住临时的生命周期延伸到完整表达的结尾,而不是进一步.

或者,类可以重载一元运算&符(具有自然语义)

class SomeValue {
public:
  SomeValue *operator &() { return this; }
  ...
};
Run Code Online (Sandbox Code Playgroud)

然后可以用于相同的目的

app->doStuff(*&SomeValue("value1"));
app->doStuff(*&getNiceValue());
Run Code Online (Sandbox Code Playgroud)

虽然&以此解决方法为唯一目的而超越运营商并不是一个好主意.它还允许一个人创建指向临时的指针.

  • 你也可以把它变成一个自由函数`template <class T> T&as_lvalue(T && v){return v; }`. (2认同)