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很好。我已经更新,使两个构造函数都是模板。