0

I would like to create floats and integers types that enforce some upper and lower bounds but otherwise behave just like primitive float and integer values.

I thought about making structs with their own overloaded operator= that enforces the bounds.

But I don't see a solution that doesn't involve making a float/int member variable and using that instead of a regular float/int.

Is there a way to make objects that can be used just like primitive types?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
romanbird
  • 178
  • 9
  • https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading – spectras Oct 26 '18 at 18:39
  • 1
    Exactly the same way, no., but you can get really close. What sort of differences are showstoppers for you? – user4581301 Oct 26 '18 at 18:40
  • You can try Ada language. In Ada you can write `type ConstrainedInt is range -5 .. 10;` – user7860670 Oct 26 '18 at 18:42
  • 2
    What's wrong with struct members exactly? If done right, it will be just as space-efficient as a plain primitive variable, and you'll need to do some runtime logic to enforce the constraints anyway, which operator overloads handle perfectly. – alter_igel Oct 26 '18 at 18:45
  • If you're really against structs, you could implement something like this using template metaprogramming, but you wouldn't be able to use `float` at all, and everything would have to happen at compile time, making it useless in just about any non-academic setting. And it would be nothing at all like a primitive type. – alter_igel Oct 26 '18 at 18:47
  • 1
    Yes, you can make structs that behave just like primitive types by overloading the appropriate operators. See, for example, [this shameless plug](https://stackoverflow.com/a/13730310/212858). It doesn't currently implement eg. the [binary arithmetic operators](https://en.cppreference.com/w/cpp/language/operators), but they're absolutely feasible. – Useless Oct 26 '18 at 18:51
  • 1
    It's unclear to me what you mean by _"used just like primitive types"_. Do you mean that you want your unique type to have the same _capabilities_ as a primitive? Do you mean that you want your types to work anywhere that a `float` or `int` is expected? – Drew Dormann Oct 26 '18 at 18:56

1 Answers1

2

I would like to create floats and integers types that enforce some upper and lower bounds but otherwise behave just like primitive floats and ints.

That's fine. You might as well start here, but of course you can write your own too.

I thought about making structs with their own operator= that enforces the bounds

Worked for me.

... involve making a float/int member variable

Yep.

... and using that instead of a regular float/int

If you're worried about having to write wrapper.value everywhere instead of just wrapper, don't be.

You can handle all of this with conversion operators like the linked answer's

operator T const& () const { return val_; }

when you want the wrapper type to implicitly convert back to the primitive.

For arithmetic, you can implement the binary arithmetic operators directly if you don't want to convert between the primitive and bounded types.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • prefer to making the conversion operator `explicit`, to avoid accidental casts from your 'safe' type to an 'unsafe' variant. – Mooing Duck Oct 26 '18 at 19:54
  • Well the linked answer showed it being used for `double` so yes, obviously. The _bounds_ have to be integers with that scheme, which is a limitation (but suited the question). If you need something different it could just take as a type parameter some struct with `static constexpr float lower()/upper()` methods instead of the literal `Tmin,Tmax` non-type parameters. – Useless Oct 28 '18 at 18:26