在没有命名对象的情况下传递非常量引用?

问题描述 投票:0回答:1

我有一个类

StreamRead
代表一个文件,我想将其传递给其他类的构造函数,例如
Bitmap
。但是,我无法直接将未命名的临时对象传递给
Bitmap


Bitmap::Bitmap(StreamRead & in) {
    // "in" cannot be const because StreamRead's reading operations
    // change the file position
    ...
}

int main() {
    Bitmap image(StreamRead("filename.png")); // illegal
}

我找到了三种方法来解决这个问题。最后一个是我正在使用的,因为它符合人体工程学,没有使用

mutable
,但我担心它在 C++ 中可能没有很好地定义:

  • 创建 StreamRead 对象时始终创建命名临时对象
  • StreamRead
    mutable
    中制作文件位置成员及其读取方法
    const
  • 提供
    StreamRead
    一个返回自身引用的方法,并将此调用链接到构造函数上。

所以我的代码现在看起来像这样:

StreamRead & StreamRead::pass() {
    return *this;
}

int main() {
    // legal, but is this well-defined?
    Bitmap image(StreamRead("filename.png").pass()); 
}

我可以依赖

pass()
始终提供有效的参考吗?或者 C++ 编译器是否允许做一些时髦的事情,比如在获得对它的引用后立即销毁
StreamRead
对象,然后使用悬空引用调用 Bitmap 的构造函数?

c++ reference parameter-passing
1个回答
0
投票

我认为你的第三种方法应该可以正常工作,因为函数参数的范围一直延伸到函数末尾。

还有一些其他选项可以让代码正常工作。首先,您可以使用 const 左值引用限定符声明函数参数

Bitmap::Bitmap(const StreamRead & in) {}

或者你可以做通用参考

template<typename T>
Bitmap::Bitmap(T&& in) {}

无法将未命名临时值传递给原始函数的原因是因为未命名临时值是纯右值,并且您的参数具有左值引用限定符,这意味着引用的值可以更改。但是,纯右值不绑定到名称,因此您无法真正更改它。您可以更改值为 5 的变量的值,但无法更改纯值 5。

© www.soinside.com 2019 - 2024. All rights reserved.