1

So i'm trying to serialize information into a string using std::stringstream but the compiler doesn't like me.

enum PacketType : unsigned int {
        PacketType_unknown = 0,
        PacketType_ping,
        PacketType_server_welcome,
        PacketType_client_greetings,
    };
std::stringstream ss;
unsigned int v;
PacketType p;
ss << (unsigned int)somevalue;
// error here
ss >> p;

The error is:

no match for 'operator>>' (operand types are 'std::stringstream' {aka 
'std::__cxx11::basic_stringstream<char>'} and 'PacketType')GCC

EDIT: Forgot too add so many stuff because I thought it wasn't important

walnut
  • 21,629
  • 4
  • 23
  • 59
  • Please paste the error you are getting – borievka Nov 26 '19 at 00:11
  • @borievka oops forgot –  Nov 26 '19 at 00:13
  • You didn't provide the whole code. But thanks to the error, we know, that `somevalue` is of type `CPacket::PacketType`, and you haven't provided an overloaded `operator>>` to automatically put it to the stream. You need to either provide that operator, or call some method, typically `to_string()`. But `CPakcet::PacketType` has to provide this function – borievka Nov 26 '19 at 00:15
  • @borievka CPacket::PacketType is an enum forgot too add that too :p –  Nov 26 '19 at 00:20
  • 1
    I'd guess `ss >> static_cast(p);` – Jazzwave06 Nov 26 '19 at 00:25
  • 1
    I don't see an `operator >>` overload that handles `PacketType`. Lines up pretty well with the error message. – user4581301 Nov 26 '19 at 00:27
  • @sturcotte06 As a `static_cast` this will be ill-formed and wont compile. As a `reinterpret_cast` it will cause undefined behavior because of an aliasing violation when written to. – walnut Nov 26 '19 at 00:40

1 Answers1

1

I finally figured it out, the reason why my code wasn't working was because...

PacketType != unsigned int. PacketType is it's own type. even though it's based off unsigned int.

So all i had to do was

unsigned int s;
ss >> s;
somevalue = static_cast<PacketType>(s);

still weird though... shouldn't PacketType inherit unsigned int.

  • 4
    No, despite similar syntax to classes, the enum does not "inherit" the `unsigned int` and cannot be implicitly converted to one. Indeed, _that's the whole point of a scoped enum_. Just case it to `unsigned int` yourself... – Lightness Races in Orbit Nov 26 '19 at 00:35
  • sometimes I'm glad I check new comments before commenting. Saved me some typing there. Which I totally burned by making this comment. – user4581301 Nov 26 '19 at 00:37
  • The code shouldn't work, you need to explicitly `static_cast(s)` in order to assign it to `somevalue`. – walnut Nov 26 '19 at 00:46
  • @uneven_mark the compiler has no words against it becouse i defined it as`Packet::Type : unsigned int` –  Nov 26 '19 at 00:48
  • GCC, Clang and MSVC disagree in my test: https://godbolt.org/z/mnNFdS (Adding the C++17 flags doesn't change that.) – walnut Nov 26 '19 at 00:50
  • @uneven_mark Weird i'm using GCC right now and it's working just fine. but i'll change it too static_cast(s) too keep cross compatibility –  Nov 26 '19 at 00:53
  • It will work in GCC if you are using the `-fpermissive` flag, but you really shouldn't do that. If you are not using that then please check the godbolt link and enter your test case with your GCC version and compiler flags. I would be interested in what you are doing differently. I am referring to the godbolt I linked. I forgot to set the `-std=c++17` flags there (but it doesn't matter). – walnut Nov 26 '19 at 00:56
  • @uneven_mark i'm not using that flag if i'm aware... why that works on my system deserves a questions of its own –  Nov 26 '19 at 00:58