从std :: stringstream读取uint8_t作为数字类型

bre*_*att 9 c++

我的理解是,uint8_t从a 中读取stringstream是一个问题,因为stringstream它将把它解释uint8_t为a char.我想知道如何uint8_tstringstream一个数字类型中读取a .例如,以下代码:

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
    uint8_t ui;
    std::stringstream ss("46");
    ss >> ui;
    cout << unsigned(ui);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印出来52.我想打印出来46.

编辑:另一种做法只是读取string距离stringstream,然后转换解决方案uint8_t,但是这打破了很好的链接属性.例如,在我必须编写的实际代码中,我经常需要这样的东西:

   void foobar(std::istream & istream){
       uint8_t a,b,c;
       istream >> a >> b >> c;
       // TODO...
   }
Run Code Online (Sandbox Code Playgroud)

Dan*_*ica 6

您可以输入超载operator>>uint8_t,如:

std::stringstream& operator>>(std::stringstream& str, uint8_t& num) {
   uint16_t temp;
   str >> temp;
   /* constexpr */ auto max = std::numeric_limits<uint8_t>::max();
   num = std::min(temp, (uint16_t)max);
   if (temp > max) str.setstate(std::ios::failbit);
   return str;
}
Run Code Online (Sandbox Code Playgroud)

现场演示:https://wandbox.org/permlink/cVjLXJk11Gigf5QE

说实话,我不确定这样的解决方案是否没有问题.更有经验的人可能会澄清.


UPDATE

请注意,这个解决方案不是一般适用于std::basic_istream(以及它的实例std::istream),因为是一个重载operator>>unsigned char:[istream.extractors] .然后,行为将取决于如何uint8_t实现.

  • @DanielLangr“显然,编译器优先考虑将ui转换为char的简单隐式转换。” –这种隐式转换不适用于引用。但是,流的std :: operator &gt;&gt;有一个unsigned char&重载。我不确定是什么原因导致明显的歧义得到解决,而倾向于`std`版本,但高度怀疑libstdc ++中的以下专业化:`extern template istream&operator &gt;&gt;(istream&,unsigned char&);`–它显示了我想对标准函数进行模棱两可的重载是一个非常糟糕的主意。 (2认同)