有啥方法可以包装 boost“tee”流的构造以进行自动类型推断?

Posted

技术标签:

【中文标题】有啥方法可以包装 boost“tee”流的构造以进行自动类型推断?【英文标题】:Any way to wrap construction of boost "tee" stream for automatic type deduction?有什么方法可以包装 boost“tee”流的构造以进行自动类型推断? 【发布时间】:2018-09-06 18:40:15 【问题描述】:

boost::iostreams::tee 和 company 有一些嘈杂/重复的用法,如下所示:

C++ "hello world" Boost tee example program

我们的目标是制作类似的东西:

auto myTeeStream = make_tee(std::cout, myfile);

在尝试使用函数 make_tee 包装此用法以允许对参数进行自动类型推导后,我意识到复制和移动构造函数都不适用于必要的类型。

那么:有没有一种理智的方法可以在 c++11 中包装 tee 流创建

这是由于删除了复制构造函数和缺少移动构造函数而导致编译失败的尝试:

#include <iostream>
#include <ostream>
#include <fstream>

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>

template <typename StreamT1, typename StreamT2>
boost::iostreams::stream<boost::iostreams::tee_device<StreamT1, StreamT2> >
make_tee(StreamT1 & t1, StreamT2 & t2)

    using boost::iostreams::stream;
    using boost::iostreams::tee;
    return stream<decltype(tee(t1,t2))>(tee(t1,t2)); // compile error
    //return std::move(stream<decltype(tee(t1,t2))>(tee(t1,t2))); // also fails of course



int main()

    
        // desired usage
        std::ofstream myFile("file.txt");
        auto && myTee = make_tee(std::cout, myFile); // required from here
    
    
        // noisy default usage
        std::ofstream myFile("file.txt");
        using boost::iostreams::tee;
        using boost::iostreams::stream;
        auto && myTee = stream<decltype(tee(std::cout, myFile))>(tee(std::cout, myFile));
    
    return 0;

来自clang++ --std=c++11 teetest.cpp 的错误是:

teetest.cpp:14:12: error: call to implicitly-deleted copy constructor of 'boost::iostreams::stream<boost::iostreams::tee_device<basic_ostream<char>, basic_ofstream<char> > >'

【问题讨论】:

相关:***.com/questions/7903903/c-copy-a-stream-object 【参考方案1】:

在 c++17 中使用 "保证复制省略" 编译良好。

在 c++11 中,你可以使用return ..:

template <typename StreamT1, typename StreamT2>
boost::iostreams::stream<boost::iostreams::tee_device<StreamT1, StreamT2> >
make_tee(StreamT1 & t1, StreamT2 & t2)

    using boost::iostreams::stream;
    using boost::iostreams::tee;
    return tee(t1,t2);

Demo

【讨论】:

是的!谢谢你。我不知道统一初始化保证在 C++11 中没有副本。 @Catskul 实际上并没有给你guaranteed RVO。它直接构造返回值,然后通过引用捕获它来延长该临时的生命周期。 鉴于 c++17,我强烈考虑简化为 auto make_tee(T&amp; t, U&amp; u) return boost::iostreams::tee(t, u); (将 ADL 保持在 tee() 上可能有价值,但我不确定这是一个有意识的扩展点。在事实上它很容易导致ambiguous scenarios) @sehe:我试图保留 OP 的代码,但实际上,我不确定这里是否需要 ADL。

以上是关于有啥方法可以包装 boost“tee”流的构造以进行自动类型推断?的主要内容,如果未能解决你的问题,请参考以下文章

boost-python:如何提供自定义构造函数包装函数?

返回 boost::shared_ptr 和从返回的原始指针构造 boost::shared_ptr 有啥区别?

Boost.Python:在类外定义构造函数

有啥好方法可以简化由多个功能包装的组件?

IO流06_处理流

boost.asio 和文件 i/o 有啥关系?