繁体   English   中英

使类在流上模板化可以处理std :: cout和std :: ofstream

[英]Making a class templatized on stream handle both std::cout and an std::ofstream

我想编写在Stream上模板化的类StreamContainer:

#ifndef STREAMCONTAINER_HPP
#define STREAMCONTAINER_HPP
#include <string>
#include <iostream>
    template<typename Stream>
    class StreamContainer
    {
    public:
        StreamContainer(std::ostream& os)
            : m_stream(os) {} 
    private:
        Stream & m_stream;
    };

#endif

我认为以下客户端代码可以工作:

#include "StreamContainer.hpp"
#include <fstream>
int main(int argc, char argv[])
{
    std::ofstream ofs;
    ofs.open("c:\\code\\temp.txt");
    StreamContainer<decltype(std::cout)> coutContainer(std::cout); // C2439
    StreamContainer<std::ofstream> fileContainer(ofs); // C2664
}

但这至少在Visual C ++ 2015中不起作用。尝试传递std :: cout会导致错误C2439(无法初始化成员),尝试传递std :: ofstream对象会导致错误C2664(std :: basic_ofstream构造函数)无法将参数从std :: basic_ostream转换为const char *)。 我也尝试过使用move构造函数,但是还有其他问题。 任何有关如何解决此问题的建议将不胜感激。

这个:

StreamContainer(std::ostream& os)

应该:

StreamContainer(Stream& os)

否则,您的ofstream实例将尝试对一个ostreamos )进行一个ofstream&引用( m_stream )。 另一个方向很好,但这是将基类对象分配给派生的引用。


由于无法从构造函数参数中推断出类模板参数,因此这是引入工厂函数的一个好用例:

template <typename Stream>
StreamContainer<Stream> make_container(Stream& s) {
    return StreamContainer<Stream>{s};
}

这样您就不必重复参数,或者更糟的是,使用decltype

auto coutContainer = make_container(std::cout);
auto fileContainer = make_container(ofs);

或者,实际上,如果您不需要任何特定于类型的信息,那么两者都可以是ostream&

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM