DEV Community

Discussion on: Is there a way to have raw-types in (modern) C++?

Collapse
 
baenencalin profile image
Calin Baenen

Could you provide an example of how your example helps? I still think I need raw types, because the goal is to have multiples match up, so that Token<int, 2> can also be grouped with a Token<std::string, "hello">. - With raw types, I could just say Token, and I would only have to figure out what type is being used (which isn't too hard in C++).

Collapse
 
totally_chase profile image
Phantz

Ah, you want a heterogenous array, not a polymorphic one. If it's not at all possible to design your API in a way to need heterogenous arrays - your only option is to use std::variant. You can't have just Token though, since that immediately kills static typing.

You'll most likely need to throw in a whole bunch of holds_alternative checks before you can actually use the value though. Yeah, I know it's painful - but that's not an inherent drawback of type safe static typing, it's just C++.

Thread Thread
 
baenencalin profile image
Calin Baenen

but that's not an inherent drawback of type safe static typing, it's just C++.

C++ is my favorite language, but in this regard, it treats things very stupidly.
Sure, Token (kind of) kills static typing, but you must admit, for the purpose of having a flexible array (or any structure), allowing raw types would be nice as an option. -- Or, at least make it easier to reach the end goal for something like this.
(Maybe I'll just make my own heterogeneous array implementation, if that's considered "okay" by most people's logic.)

Collapse
 
totally_chase profile image
Phantz • Edited

Also, regarding an API redesign from my previous reply. This is what I generally see token types implemented as, for parsers/lexers-

data TokenValue = StringLiteral String | IntConst Int

data Token = Token
  { tokenValue :: TokenValue
  ; tokenType :: TokenType
  ; posColumn :: Int
  ; posLine :: Int
  }
Enter fullscreen mode Exit fullscreen mode

That's haskell, but it should be readable regardless. Notice how the raw token value is the std::variant, and the Token is a wrapper around it. The T that you pass to your Token template is not present here, because it doesn't need to be present. TokenValue is actually a tagged union. std::variant is a really roundabout and overly complex way of doing tagged unions - so it's equivalent.

I really don't think you'll ever need to track the T that you use for the value field. It should just be tracked by the tagged union (since it's a runtime concept).