如何从 std::shared_ptr<boost::iostreams::stream<:stream::null_sink>> 强制转换为 shared_ptr<std::ofstream>

How to cast to a shared_ptr<std::ofstream> from std::shared_ptr<boost::iostreams::stream<boost::iostreams::null_sink>>

提问人:L Holness 提问时间:5/31/2023 最后编辑:Remy LebeauL Holness 更新时间:5/31/2023 访问量:106

问:

我有一个成员是.shared_ptr<ofstream>

在特定情况下,我想抑制输出,并使流成为 .应该做我想做的事。boost::iostreams::stream<boost::iostreams::null_sink>

我宁愿避免此线程中的建议,它在包装在 .ofstream(nullptr)make_shared()

我对其他空建议持开放态度,但它需要跨平台。ofstreamshared_ptr

使用输出(非抑制)初始化它的工作原理:

InputReader::InputReader(std::string filepath2, std::string filepathmain){
    this->thestreamstruct.themainWriter = std::move(std::make_shared<std::ofstream>(filepathmain.c_str()));
}

在抑制的初始值设定项中,我声明了 null sink 流,而不是初始化 ,然后想将其强制转换为 并将其分配给成员:shared_ptrofstreamofstream

InputReader::InputReader(std::string filepath2, Model* amodel){
    std::shared_ptr<boost::iostreams::stream<boost::iostreams::null_sink>> nullOstream = std::make_shared<boost::iostreams::stream<boost::iostreams::null_sink>>((boost::iostreams::null_sink()));
    std::shared_ptr<std::ofstream> nullost = std::move(std::dynamic_pointer_cast<std::ofstream>(nullOstream)); 
    this->thestreamstruct.themainWriter = nullost; 
}

这失败了,因为 和 提升流之间没有直接转换。std::ofstream

但是我可以分配一个 ref 作为升压空接收器??ofstream

boost::iostreams::stream<boost::iostreams::null_sink> nullout { boost::iostreams::null_sink{} };
std::ostream& out = nullout;

这很好,所以一定有底层的某个地方?我只是不知道如何把它包装成一个.ofstreamshared_ptr

C++ IOSTREAM 提升-IOstreams

评论

3赞 Miles Budnek 5/31/2023
为什么而不是?std::ofstreamstd::ostream
0赞 Remy Lebeau 5/31/2023
如果您只想禁止将数据写入输出文件,则可以使用其继承的 rdbuf() 方法交换一个不写入任何内容的其他方法。然后在您想停止抑制时换回原始版本。ofstreambasic_streambuf
0赞 Red.Wave 5/31/2023
看:仅此一项就意味着你 nead ,而不是 .这也更可控。std::ostream& out= nullout;ostreamofstream

答:

0赞 sehe 5/31/2023 #1

在不泄漏缓冲液的情况下,煞费苦心地获得正确的寿命:

Live On Coliru(科里鲁生活公寓)

#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>

using std::filesystem::path;
using sofstream = std::shared_ptr<std::ofstream>;

sofstream make_null() {
    struct both {
        boost::iostreams::stream_buffer<boost::iostreams::null_sink> b{{}};
        std::ofstream                                                ofs;
    };
    auto s = std::make_shared<both>();
    static_cast<std::ios&>(s->ofs).rdbuf(&s->b);
    return sofstream(s, &s->ofs);
}

sofstream make(path p) { return std::make_shared<std::ofstream>(p); }

int main() {
for (auto ss : { make_null(), make("test.txt") }) {
        *ss << "hello world\n";
        assert(ss->good());
        *ss << "bye world\n";
        assert(ss->good());
    }
}

我个人认为这整个方法可能是聪明的一半,你应该使用而不是无论如何。(例如 http://coliru.stacked-crooked.com/a/333cc9871c5e977bstd::ostream&std::ofstream&)

评论

0赞 L Holness 5/31/2023
换成,因为它看起来确实是更好的解决方案,但我也有这个在后口袋里,谢谢!ostream