Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用nullptr交换流的缓冲区以模拟移动?_C++_Stream - Fatal编程技术网

C++ 用nullptr交换流的缓冲区以模拟移动?

C++ 用nullptr交换流的缓冲区以模拟移动?,c++,stream,C++,Stream,我想在一个结构中存储一个std::istream,并能够从另一个流构造它。目前,我有以下几点: struct A { A(std::istream &in) : in_(in.rdbuf()) { } protected: std::istream in_; }; A(std::stringstream("hello world!")); 这只允许从已创建的对象创建类型为A的对象,但我希望能够: struct A { A(std::istream &i

我想在一个结构中存储一个
std::istream
,并能够从另一个流构造它。目前,我有以下几点:

struct A {
    A(std::istream &in) : in_(in.rdbuf()) { }
protected:
    std::istream in_;
};
A(std::stringstream("hello world!"));
这只允许从已创建的对象创建类型为
A
的对象,但我希望能够:

struct A {
    A(std::istream &in) : in_(in.rdbuf()) { }
protected:
    std::istream in_;
};
A(std::stringstream("hello world!"));
我为
std::istream
的右值引用添加了以下重载
A

A(std::istream &&in) : in_(in.rdbuf()) {
    in.rdbuf(nullptr); // (1)
}
我添加了
(1)
,以避免在序列点之后销毁缓冲区,但我不知道是否定义了此行为,或者这是否真的有意义


我可以根据标准像这样“移动”流缓冲区吗?如果没有,这是否适用于标准实现和流(
std::stringstream
std::fstream
,…)?

最好避免处理缓冲区,让对象在内部为我们完成工作

我提议如下。使用模板,我们可以确保在将流移动到结构中时构造完整类型的共享指针

#include <sstream>
#include <iostream>
#include <fstream>
#include <memory>
#include <typeinfo>

struct A {
    template<typename T>
    A(T& is) : is{is}
    {
        std::cout << "Only taking a reference. Not taking ownership of std::istream.\n";
    }

    template<typename T>
    A(T&& is) : own_is{std::make_unique<T>(std::move(is))}, is{*own_is}
    {
        std::cout << "using move. Not sliced.\n";
    }

    void print_stream_type()
    {
        std::cout << typeid(is).name() << '\n';
    }
protected:
    std::unique_ptr<std::istream> own_is;
    std::istream& is;
};

int main()
{
    A a1{std::stringstream{"hello world!"}};

    A a2{std::cin};

    std::ifstream ifs{"input.txt"}; 
    A a3{ifs};

    A a4{std::ifstream{"input.txt"}};

    a1.print_stream_type();
    a2.print_stream_type();
    a3.print_stream_type();
    a4.print_stream_type();

}
#包括
#包括
#包括
#包括
#包括
结构A{
模板
A(T&is):is{is}
{

std::cout在任何情况下都将
struct A
拥有流?至于您的问题,基本上说没有关联的流缓冲区是可以的。因此,将其设置为空指针当然是可以的。但这不是权威性的。@rex No-在第一种情况下,流必须在
A
实例旁边保持活动时间(这通常可用于
std::cin
)。如果流被创建为共享指针,那么您可以在
struct a
中存储指向基的共享指针,即
std::istream
而不会丢失完整的对象,例如
std::stringstream
std::ifstream
。在我看来,否则切片是一种风险。因此,如果您将左值传递给构造函数您希望存储引用,但如果传递了一个右值,则希望将其移动到
a
?不幸的是,这不起作用-
a(std::istream&)
比类型为
std::istream
的对象的模板更匹配,但模板构造函数比类型为从
std::istream
派生的对象的模板更匹配,例如
std::ifstream if;a{if};
不编译。@Holt很好。我已经更新,使两个构造函数都是模板。