【问题标题】:How to output unsigned/signed char or <cstdint> types as integers with << in C++如何在 C++ 中使用 << 将 unsigned/signed char 或 <cstdint> 类型输出为整数
【发布时间】:2010-10-29 07:48:39
【问题描述】:

背景:

我有模板流运算符(例如 operator &lt;&lt; (ostream &amp;, std::vector &lt;T&gt;))(输出可能是某种 8 位整数类型的容器元素,(例如 unsigned charint_least8_t 等)。

问题:

默认这些类型输出为char (ASCII)。 我只将char(或wchar_t 或其他)用于ASCII 变量,从不使用无符号/有符号类型。 如何让这些其他 8 位类型始终输出为 signed int / unsigned int(数字),即使调用者不知道类型?

第一次尝试:

我已经尝试(使用 GCC)例如定义 operator &lt;&lt; (ostream &amp;, unsigned char) 并在其中添加一个演员(即 stream &lt;&lt; static_cast &lt;int&gt; (value)。这适用于 unsigned char 值,但随后 uint8_t 仍将输出为 char

相同的底层类型(即unsigned/signed char 不能用于重载,因此我无法定义例如operator &lt;&lt; (ostream &amp;, int_fast8_t) 的重载。

【问题讨论】:

  • 可以添加一些代码示例吗?
  • 能否请您发布一些代码以便我们更好地理解?
  • 你弄糊涂了……哎呀,评论太长了。编辑:在下面查看我的答案
  • 对不起大家,希望现在更清楚了。

标签: c++ templates operator-overloading char cstdint


【解决方案1】:

您将变量中保存的实际数据与您选择用于打印它的任何表示混淆了。

这样想:charsintsdoubleslongs,不管怎样,它们都是供你存储数字的内存块。字符是介于 0 和255(或 -128 和 127)——您可以选择将其表示为 ASCII 字符、数字或借助 OpenGL 的天空中的星星。

如果您想查看字符“a”后面的数字,只需指示您的程序将那块内存(对您来说包含“a”)视为一个数字。使用演员表。这里:

http://www.cplusplus.com/doc/tutorial/typecasting/

看看有没有帮助!

【讨论】:

  • +1 用于解决 OP 的潜在混淆,而不是显示使用哪种语法。
  • 这在模板运算符中是不可能的,因为它需要我事先知道类型。
【解决方案2】:

想到的一种方法是使用类型特征来定义每种类型的输出类型。您必须手动为每种类型声明。可以将特征定义为模板结构,该模板结构专用于具有与数据类型本身不同的输出类型的每种数据类型:

template< T >
struct output_trait {
    typedef const T & output_type;
}

在你的运算符中你写:

std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;

默认情况下这不会进行强制转换,但对于 output_trait 专门针对的类型,它将进行强制转换:

template<>
struct output_trait< unsigned char > {
    typedef unsigned int output_type;
}

【讨论】:

  • 谢谢,我自己也猜不到。 (其他答案完全错过了关于模板容器的部分。)
  • (应该是static_cast&lt; output_trait&lt; T &gt;::output_type &gt;( variable )
  • @stellarvortex:谢谢,已修复。
  • +1 - 真是个好主意。 @stellavortex:但是您仍然应该知道您的容器将具有哪些类型,以便能够为每种类型专门化 output_trait,正如您所说 - “事先知道类型”。这个问题对我来说真的很困惑和不清楚。不仅对我来说,正如我看到的其他答案一样。
  • 基洛夫,你错了。你读过 Space Cowboy 的笔记,还是只是代码?模板类是自动的,因此所有非专业版本都将使用该模板类。 (然而 typedef 应该是 typedef T const &amp; output_type;,以避免复制。)
【解决方案3】:

你可以简单地投射它:

#include<iostream>

int main()
{
 uint8_t blah = 65;
 std::cout << static_cast<int>(blah) << "\n";
 return 0;
}

65

【讨论】:

  • 这在模板运算符中是不可能的,因为它需要我事先知道类型。
【解决方案4】:

如果我没听错的话.. 输出如下:

std::cout << ( unsigned int )char << '\n';

或者更多c++风格——使用static_cast,例如:

int main()
{
    char a = 'a';
    char b = 97;
    std::cout << static_cast< unsigned int >( a ) << '\n';
    std::cout << static_cast< unsigned int >( b ) << '\n';
    return 0;
}

std::cout 都将打印相同的内容:第一个 - 'a' 的 ASCII 码:97,第二个 - 只是值 97,存储在 b 中。 ab 两者完全相同。

【讨论】:

  • 10x,反正 xD 如果发帖者用例子解释自己,那就太好了(:
  • 有这样的问题不容易。它发生在我们所有人身上:如果我们真的能够准确地描述我们的问题,我们早就找到了解决方案。我最终回答了,看看我是否可以进一步解释一下xD
  • 是的,你说得对,但我的意思是,张贴者可以说:“例如,如果我在无符号字符中存储了一个值 97,如何将其打印为数字97,而不是打印 a。”但你是绝对正确的,这并不总是可能的(y)
  • 这在模板运算符中是不可能的,因为它需要我事先知道类型。
  • 你说过:"How do I get these other 8-bit types to **always** be output as signed int / unsigned int (numbers) instead, even when the caller doesn't know the type?" - 你不需要事先知道类型。由于您希望输出为unsigned int,因此您不必关心 T 是什么。此外,如果无法进行此类转换(例如,如果容器具有某些用户定义的类型,则无法将其强制转换为 @ 987654334@),这将是一个编译时错误,因为模板是在编译时实例化的。
【解决方案5】:

您可以在输出之前强制转换它们:

std::cout << (unsigned int) container[index];

【讨论】:

  • container 并不意味着“字符串”或数组,或某事。它表示一个包含其他对象/变量的对象。所以,如果你有一个里面有两个字符的结构,你不能像这样输出它们(:。无论如何,我没有拒绝你的答案,因为我理解你的意思,但不要混淆这些术语,请(:
  • 感谢您的澄清。我只是试图给出一个最小的、抽象的例子。当我开始写我的答案时,其他(更好的!)答案不存在。
猜你喜欢
  • 1970-01-01
  • 2012-09-27
  • 2020-10-11
  • 2023-02-10
  • 1970-01-01
  • 2011-01-19
  • 2017-03-27
  • 2012-04-11
  • 1970-01-01
相关资源
最近更新 更多