繁体   English   中英

重载运算符<<(无符号字符类型定义为字节)

[英]Overload operator<< (unsigned char typedef as byte)

我想重载(劫持?) ostreambasic_ostream<unsigned char>以便它停止尝试将八位字节(无符号字符)显示为可打印字符。

我和cout和朋友一起在屏幕上放笑脸已经太久了。 而且我厌倦了使用演员表: hex << int(0xFF & b) <<...

是否可以覆盖标准行为? 我已经尝试过模板和非模板覆盖。 他们编译,但似乎没有被调用。

问题是已经有一个

template<class charT, class traits>
std::basic_ostream<charT,traits>& 
operator<<(std::basic_ostream<charT,traits>&, charT);

namespace std中。 由于basic_ostream<>也在此命名空间中,因此当您 output 为unsigned char时,ADL 会选择它。 添加您自己的重载可能会使调用运算符不明确,或者您的重载将被默默忽略。

但即使它可以工作,它也会很脆弱,因为忘记一个包含可能会在没有编译器任何诊断的情况下巧妙地改变代码的含义。
还有更多:每个查看此类代码的维护程序员都会假设调用了标准运算符(当他向代码添加另一个 output 语句时,永远不会想到添加包含)。
简而言之,最好添加一个 function来做你想做的事情。

一个合理的语义替代方案可能是添加一个 stream 操纵器,该操纵器调用您想要的 output 格式。 不过,我不确定这在技术上是否可行。

卢克是正确的。

您当前方法的更快替代方法 - 如果您不介意十进制 output - 是将 char 提升为int

unsigned char c = '!';
os << +c;

我不明白这将如何征税!

#include <iostream>
#include <string>       // std::char_traits

typedef unsigned char       UChar;
typedef UChar               Byte;

typedef std::char_traits<char>      CharTraits;
typedef std::char_traits<wchar_t>   WCharTraits;

typedef std::basic_ostream< char, CharTraits >      CharOStream;
typedef std::basic_ostream< wchar_t, WCharTraits >  WCharOStream;

CharOStream& operator<<( CharOStream& stream, UChar v )
{
    return stream << v+0;
}

int main()
{
    char const      c   = 'c';
    UChar const     u   = 'u';

    std::cout << c << '\n' << u << std::endl;
}

这与 MSVC 10.0 和 MinGW g++ 4.4.1 配合得很好,并且可以与 Comeau Online 一起干净地编译,所以我相信它在形式上是可以的。

干杯&hth.,

阿尔斯是对的,你所要求的不会发生。

您能做的最好的事情就是编写自己的 IO 机械手 ( iomanip ) 来为您施展魔法。 在这种情况下,您需要一个采用unsigned char的 function (尽管我强烈建议使用<stdint.h>中的uint8_t )。

#include <stdint.h>
#include <ostream>

class asHex
{
public:
    asHex(uint8_t theByte): value(theByte) {}
    void operator()(std::ostream &out) const 
        { std::ios::fmtflags oldFlags = out.flags; out << std::hex 
              << std::setw(2) << std::setfill('0') << std::uppercase << theByte; 
          out.flags(oldFlags); }
private:
    uint8_t theByte;
};

std::ostream& operator<<(std::ostream &out, asHex number)
{
    number(out); return out;
}

然后你可以写:

cout << asHex(myByte);

您可以将构造函数添加到asHex ,甚至将其设为模板 class 以支持 16、32 和其他位数。

(是的,我知道<stdint.h>不是官方的 C++ header,但我宁愿将其定义放在全局命名空间而不是std::中,而不必执行using namespace std;它将所有内容都转储到全局命名空间中.)

由于 ADL,将调用标准operator<< 尝试明确限定您的通话:

::operator<<(os, 42);

您不能直接覆盖std::cout的行为。 如果任何开发代码都可以改变其他代码使用的标准库的行为,那就太容易出错了。

可以创建自己的 class 来模拟std::cout的行为,并改用该 object。

class SpecialCout
{
    template <typename T>
    friend SpecialCout& operator<< ( SpecialCout const& scout, T const &t )
    {
        // Do any adjustments to t here, or decide to return early.

        std::cout << t;
        return *this;
    }

};

extern SpecialCout scout;

暂无
暂无

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

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