构造函数中可移动类型的C ++右值 [英] c++ rvalue of moveable type in constructor

查看:81
本文介绍了构造函数中可移动类型的C ++右值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C ++ 11并试图构造一个拥有如下可移动类型的类:

I am using C++11 and trying to construct a class that owns a movable type like this:

class foo {
    std::istream input;

public:
    foo(std::istream && in): input(in) { }
};

然后实例化对象:

foo var1(std::ifstream("/tmp/something"));

但是编译器总是抱怨我在调用一个删除的构造函数。

But the compiler always complains that I am calling a deleted constructor. Is this even possible?

clang++ -stdlib=libc++ -std=c++0x foo.cpp 
foo.cpp:7:30: error: call to deleted constructor of 'std::istream' (aka 'basic_istream<char>')
    foo(std::istream && in): input(in) { }
                             ^     ~~
/usr/bin/../lib/c++/v1/istream:1740:23: note: function has been explicitly marked deleted here
extern template class basic_istream<char>;
                      ^
1 error generated.


推荐答案

不幸的是,您无法复制(甚至移动)抽象流类型 std :: istream 。您可以通过引用保留它们,但这似乎并不是您的代码想要做的。

Unfortunately you can not copy (or even move) the abstract stream type std::istream. You can hold them by reference, but that doesn't seem to be what your code wants to do.

在传递 std时:: ifstream ,我假设这是您真正要处理的流类型。与 std :: istream 不同, std :: ifstream 是一种具体类型。这种类型是可移动的,尽管不能复制。

As you are passing in a std::ifstream, I'll assume that this is the type of stream you really want to deal with. Unlike std::istream, std::ifstream is a concrete type. And this type is movable, though not copyable.

hmjd给出的答案(标记为正确的)是编写此代码的最佳方法:

The answer hmjd had, and that you marked correct, is the best way to code this:

#include <fstream>

class foo
{
    std::ifstream input;
public:
    foo(std::ifstream&& in): input(std::move(in)) { }
};

说明: foo 构造函数仅接受rvalue std :: ifstream s,这是正确的。但是一旦进入此构造函数,中的变量不再是右值(它是左值)。因此,您需要将其强制转换为右值(使用 std :: move )移动构造数据成员 input

Explanation: The foo constructor will only accept rvalue std::ifstreams, which is correct. But once you're inside this constructor, the variable in is no longer an rvalue (it is an lvalue). And thus you need to cast it back to an rvalue (using std::move) to move construct the data member input.

与任何仅移动类型( stringstream unique_ptr 未来 unique_lock 等)。

This is the same pattern that you would use with any move-only type (stringstream, unique_ptr, future, unique_lock, etc.).

这篇关于构造函数中可移动类型的C ++右值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆