C++ 非 const 右值参数解决方法

标签 c++ rvalue-reference

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

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

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

我不能将参数设为 const 引用,因为 Streams 需要更新它们的状态,例如当前流位置。

使这些 Stream 属性可变或将它们转换为常量对我来说似乎是糟糕的设计,因为这些状态对用户有明显的影响。

我有什么选择才能完成这项工作,最好不要为每个“类图像”类设置两个几乎相同的构造函数?

提前致谢。

最佳答案

What options do I have to make this work, preferrably without having two nearly identical constructors for every 'Image-like' class?

你想要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++ 非 const 右值参数解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42856079/

相关文章:

c++ - 作为对象字段的右值引用

c++ - 理解右值引用

c++ - 将数据保存和加载到文件 C++(初学者)

c++ - 返回 QList 的函数

c++ - 右值引用用法 : needed?

c++ - 从左值构造函数调用右值构造函数

c++ - 哪些类型的代码需要注意右值引用?

C++11成员类初始化顺序

C++ char* 到 int 错误

c++ - OpenGL、GLM 四元数旋转