我有一些提供基本IO的Stream类。
我希望能够编写如下代码:

Image img = Image(StreamReader("filepath"));

不幸的是,根据该标准,将rvalue引用绑定(bind)到非const lvalue引用似乎是非法的,例如Image ctor的参数。

我无法将参数设为const引用,因为Streams需要更新其状态,例如当前的流位置。

使这些Stream属性可变或const强制转换它们对我来说似乎是不好的设计,因为这些状态对用户有明显的影响。

我必须有哪些选择才能完成这项工作,而每个“类图像”类最好没有两个几乎完全相同的构造函数?

提前致谢。

最佳答案



您想要perfect forwarding。它将允许您定义一个接受const&&&的函数:

template <typename T,
          typename std::enable_if_t<!std::is_same_v<std::decay_t<T>, Image>>>
Image::Image(T&& x)
{//          ^^^
 //          "forwarding reference"

    doSomething(std::forward<T>(x));
 //             ^^^^^^^^^^^^^^^^^^
 //             keep forwarding either as an rvalue reference or lvalue
 //             reference depending on the original value category of `x`
}

用法:
Image a{StreamReader("filepath")}; // rvalue

const StreamReader s("filepath");
Image b{s}; // const lvalue

StreamReader s2("filepath");
Image c{s2}; // lvalue

如果要阻止const&被接受,则可以对特定的重载进行delete或将其添加到enable_if_t子句中:
  • Image(const StreamReader&) = delete;
    (假设类型将始终为StreamReader)。
  • std::enable_if_t<!std::is_const_v<T> && !std::is_same_v<std::decay_t<T>, Image>>
  • 关于c++ - C++非常量右值参数解决方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42856079/

    10-15 04:35
    查看更多