在 C++ 中使用流运算符<< 和 std::endl

using stream operator<< with std::endl in c++

提问人:thor 提问时间:11/22/2017 最后编辑:Hudsonthor 更新时间:3/12/2023 访问量:783

问:

我正在尝试以下C++类,以使用流运算符<<来记录此答案中的内容:

class Log
{
public:
    Log()
        : m_filename( "dafault.log" )
    {}

    // if you wanna give other names eventually...
    Log( const std::string & p_filename )
        : m_filename( p_filename )
    {}

    virtual ~Log()
    {
        // implement  your writeToFile() with std::ofstream 
        writeToFile( m_filename, m_stream, true );
    } 

    template< typename T >
    Log & operator<<( const T & p_value )
    {
        m_stream << p_value;
        return *this;
    }

private:
    std::string         m_filename;
    std::ostringstream  m_stream;
};

这适用于许多情况。但是,它在尝试流式传输时无法编译,std::endl

Log( "/tmp/my.log" ) << 1 << std::endl;

,给出如下错误:

/usr/include/c++/7/string_view:558:5: note:   template argument deduction/substitution failed:
My.cpp:375:36: note:   'Log' is not derived from 'std::basic_ostream<_CharT, _Traits>'
  Log( "/tmp/my.log" ) << 1 << std::endl;
                                    ^~~~

如何让它也一起工作?std:endl

C++ 模板 运算符 IOSTREAM IOManip

评论

6赞 Igor Tandetnik 11/22/2017
你在这里需要类似重载 (12) 的东西。 是一个函数模板,它的参数推导只有在使用时才有效。operator<<std::endl
0赞 R Sahu 11/22/2017
看看我的一个答案。希望它有用。stackoverflow.com/a/24413884/434551
0赞 Telokis 11/22/2017
@IgorTandetnik 尽管我知道可以通过添加重载来修复此错误,但我真的想知道为什么不匹配。我什至在这里尝试了一个更宽松的,但它也不匹配。编译器说.为什么?应该不能与世界上的任何东西相提并论吗?const T&std::endlcouldn't deduce template parameter ‘T’T
1赞 Igor Tandetnik 11/22/2017
@Telokis世界上什么都没有。 可以从对象或函数中推导出来 - 具有类型的事物。但不是一个函数,它是一个函数模板 - 一个无限的函数家族,所有不同类型的函数。在知道其类型并推断出 之前,需要推导或显式指定其自己的模板参数。因此,可能会起作用。Tstd::endlTlog << std::endl<char, std::char_traits<char>>
0赞 Telokis 11/22/2017
@IgorTandetnik 好吧,经过这么多年的思考,我终于明白了!谢谢你的额外精度。我完全错过了这样一个事实,即它“不仅仅是”一个功能。

答: 暂无答案