c++ - 有什么方法可以将右值/临时对象传递给需要非成本引用的函数?

标签 c++ parameters c++11 rvalue-reference lvalue

我知道 C++ 只允许右值或临时对象绑定(bind)到常量引用。 (或 something close to that ...)

例如,假设我有函数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);

那么,三个问题:

  1. 由于我不能随意更改 doStuff()getNiceValue() 的签名,这是否意味着我必须始终使用某种“名称” "(即使是多余的)我想传递给 doStuff 的任何东西?

  2. 假设,如果我可以更改函数签名,这类事情是否有通用模式?

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

谢谢

最佳答案

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

无论如何,“右值性”是生成临时对象的表达式的属性,而不是临时对象本身的属性。临时对象本身很容易成为左值,但您将其视为右值,因为生成它的表达式是右值表达式。

您可以通过在您的类中引入“右值到左值转换器”方法来解决这个问题。像,例如

class SomeValue {
public:
  SomeValue &get_lvalue() { return *this; }
  ...
};

现在您可以将非常量引用绑定(bind)到临时变量

app->doStuff(SomeValue("value1").get_lvalue());
app->doStuff(getNiceValue().get_lvalue());

不可否认,它看起来不是很优雅,但它可能被视为一件好事,因为它可以防止您不经意地做类似的事情。当然,您有责任记住临时对象的生命周期会延伸到完整表达式的末尾,而不会再继续。

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

class SomeValue {
public:
  SomeValue *operator &() { return this; }
  ...
};

然后可以用于相同的目的

app->doStuff(*&SomeValue("value1"));
app->doStuff(*&getNiceValue());

尽管仅出于此解决方法的目的而覆盖 & 运算符并不是一个好主意。它还将允许创建指向临时对象的指针。

关于c++ - 有什么方法可以将右值/临时对象传递给需要非成本引用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11943877/

相关文章:

c++ - 设计问题 : Enum or functions or something else

c++ - 参数顺序评估

c++ - "Refresh"一个 lambda 对象

C++:查找满足谓词的元组的第一个元素

c++ - 将文件流插入到 std::map

function - lua函数包括表中的参数

c# - 有没有一种巧妙、有效的方法可以用两个不同的参数调用同一个方法两次?

c++ - 包装递归可变参数模板类会改变行为。为什么?

c++ - 为右值特化 std::swap

c++ - 模型转换