重载运算符<<(无符号字符类型定义作为字节)
Overload operator<< (unsigned char typedef as byte)
我想重载(hijack?)ostream
和basic_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);
in namespace std
。由于basic_ostream<>
也在这个名称空间中,因此当您输出unsigned char
时,ADL会拾取它。添加您自己的重载可能会使调用操作符具有二义性,或者您的重载将被静默地忽略。
但是即使它能工作,它也是脆弱的,因为忘记一个包含可能会微妙地改变代码的含义,而不需要编译器的任何诊断。
还有更多:每个维护程序员看到这样的代码都会假设调用了标准操作符(当他向代码中添加另一个输出语句时,永远不会想到添加include)。
简而言之,最好添加一个函数来做您想做的事情。
Luc是正确的。
比当前方法更快的替代方案—如果你不介意十进制输出—是将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++ 4.4.1中工作得很好,并且它在Comeau Online中编译得很干净,所以我相信它是正式的。
干杯,hth。
Als是对的,你所要求的不会发生。
你能做的最好的事情就是编写你自己的IO操纵符(iomanip
)来为你完成这个魔术。在这种情况下,您需要一个接受unsigned char
的函数(尽管我强烈建议从<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
添加构造函数,甚至让它成为一个模板类来支持16位、32位和其他位计数。
(是的,我知道<stdint.h>
不是官方的c++头,但我宁愿在全局命名空间中有它的定义,而不是std::
,而不必做using namespace std;
在全局命名空间中转储所有)
由于ADL,标准operator<<
将被调用。尝试显式限定调用:
::operator<<(os, 42);
不能直接覆盖std::cout
的行为。如果任何开发代码都可以改变其他代码使用的标准库的行为,那将太容易出错。
您可以创建您自己的类来模拟std::cout
的行为并使用该对象。
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;
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 在UNIX系统中使用DIR查找文件的字节大小
- 呼叫运营商<<临时
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 当比特(而不是字节)的顺序至关重要时的持久性
- <<操作员在下面的行中工作
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?