c++ - 如何为提升日志和自定义类型定义输出流运算符

标签 c++ templates boost-log stream-operators

我能够为一个简单的结构定义输出流运算符,但不能为 std::array 定义。以下代码编译失败。出了什么问题,我该如何解决?

#include <array>
#include <iostream>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>

using hash_t = std::array< unsigned char, 32 >;

std::ostream& operator<< ( std::ostream& os, hash_t const& arr )
{
    os << "ole!";
    return os;
}

int main(int, char*[])
{
    hash_t arr;
    std::cerr << arr << std::endl; // complies cleanly
    BOOST_LOG_TRIVIAL(debug) << arr; // Error
    return 0;
}

错误来了。

海湾合作委员会(提升 1.55,gcc-4.9.2):

In file included from /usr/include/boost/log/sources/record_ostream.hpp:31:0,
                 from /usr/include/boost/log/trivial.hpp:23,
                 from trival.cpp:4:
/usr/include/boost/log/utility/formatting_ostream.hpp: In instantiation of ‘boost::log::v2s_mt_posix::basic_formatting_ostream<CharT, TraitsT, AllocatorT>& boost::log::v2s_mt_posix::operator<<(boost::log::v2s_mt_posix::basic_formatting_ostream<CharT, TraitsT, AllocatorT>&, const T&) [with CharT = char; TraitsT = std::char_traits<char>; AllocatorT = std::allocator<char>; T = std::array<unsigned char, 32ul>]’:
trival.cpp:18:30:   required from here
/usr/include/boost/log/utility/formatting_ostream.hpp:710:19: error: cannot bind ‘boost::log::v2s_mt_posix::basic_formatting_ostream<char>::ostream_type {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
     strm.stream() << value;
                   ^
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from trival.cpp:2:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::array<unsigned char, 32ul>]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)

Clang 错误(boost 1.64,clang-800.0.42.1):

In file included from /usr/local/include/boost/log/trivial.hpp:23:
In file included from /usr/local/include/boost/log/sources/record_ostream.hpp:36:
/usr/local/include/boost/log/utility/formatting_ostream.hpp:878:19: error: invalid operands to binary expression ('ostream_type' (aka
      'basic_ostream<char, std::__1::char_traits<char> >') and 'std::__1::array<unsigned char, 32>')
    strm.stream() << value;
    ~~~~~~~~~~~~~ ^  ~~~~~
/usr/local/include/boost/log/sources/record_ostream.hpp:390:51: note: in instantiation of function template specialization
      'boost::log::v2_mt_posix::operator<<<boost::log::v2_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> >,
      std::__1::array<unsigned char, 32> >' requested here
    static_cast< formatting_ostream_type& >(strm) << value;
                                                  ^
/Users/adam/GitPen/BoostLog/trival/trival.cpp:18:27: note: in instantiation of function template specialization
      'boost::log::v2_mt_posix::operator<<<boost::log::v2_mt_posix::basic_record_ostream<char>, std::__1::array<unsigned char, 32> >' requested here
        BOOST_LOG_TRIVIAL(debug) << arr;

最佳答案

你可能不喜欢这个答案。

为了让它在此刻正常工作,您需要添加 operator<<namespace std :

namespace std{
   std::ostream& operator<< ( std::ostream& os, const hash_t& arr )
   {/*...*/}
}

由于 ADL 的工作方式,它将只考虑 operator<<及其专业 namespace std

你不会喜欢它,因为将此功能添加到 namespace std不是合法的事情:

[命名空间.std]

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

也许最简单的事情是继承(并且什么也不做) std改为输入:

struct hash_t : std::array< unsigned char, 32 >{};

关于c++ - 如何为提升日志和自定义类型定义输出流运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48476828/

相关文章:

c++ - opencl 硬件上的本地内存

c++ - 模板中 sizeof 的 constexpr 无法编译

c++ - 具有非类型模板参数的多态性

c++ - 为什么不能推导出这个metametafunction的模板参数呢?

c++ - 如何在自定义格式化函数中使用 boost::log::expressions::format_date_time?

c++ - 我可以检索包含非拉丁字符的路径吗?

c++ - 如何用C++连接数据库?使用什么数据库?

C++ 模板和 C 预处理器

c++ - 针对 Boost.Log 的 g++ 静态链接错误

c++ - 在自定义 boost 日志格式函数中格式化范围属性