1

I am looking at using std::any for type erasure as part of an interface I am building, and I am left wondering why it is lacking so many operators, like "+", "==". I tinkered on Coliru here, where I extended std::any to be summable and printable into an ostream. This is only for anys holding double right now, but the concept works, it is just implementation that would need to be done to support all basic numeric data types (as long as lhs and rhs are the same type for operands).

Considering I was able to extend any like this in this short time, why is the stl implementation so limited when it comes to operands?

Any thoughts are appreciated.

d-karl
  • 98
  • 5
  • 5
    How does your extension fare when the `any` is set to hold something *without* those operators? – StoryTeller - Unslander Monica Dec 06 '18 at 12:38
  • 6
    The limitations are what kills it. You'd have to type-erase the cartesian product of the set of all possible operand types with itself, which is daunting for built-in and standard types, impossible for arbitrary user-defined types, and a huge overhead in any case. – Quentin Dec 06 '18 at 12:43
  • I accept that as a hurdle, however considering std::any is type-safe, shouldn't assignments like std::any sum(a1 + a2) for identical types of a1 and a2 work conceptually? I *do not* propose supporting every possible combination of lhs and rhs type. – d-karl Dec 06 '18 at 12:45
  • 2
    Nope, it shouldn't. `std::any` is a **container**. It isn't (and shoudn't be thought as) the actual value. Following that principle, defining operators for it would have the same meaning of, say, defining operators for `std::map`. e.g.: Not a lot. – Not a real meerkat Dec 06 '18 at 12:51
  • @d-karl restricting it to identical types could be done, you'd have to type erase all operators along with the object. But that's, again, quite a lot of forced overhead for not much functionality (and mistakes would be caught at runtime, urgh). Leaving such harnessing to the user makes more sense for a standard container type. – Quentin Dec 06 '18 at 12:51
  • The point of `std::any` is that it is a typesafe container that can contain an instance of any type. The only constraints on the contained type are those associated with `any`s constructors. Those requirements of the conteinted type are pretty basic, and don't include supporting the arithmetic (`+`, etc) or comparison (`==`, etc) operators. If the contained type is not required to support those operators, there are no obvious ways for `std::any` to support them either (the obvious way for `any` to implement such operators would be to use those same operators on the contained objects). – Peter Dec 06 '18 at 13:00
  • @Peter: That's probably superior to my answer. Why not put it in the answers section? – Bathsheba Dec 06 '18 at 13:01
  • Thanks guys, I appreciate all of your input so far, and I have accepted that std::any is not meant to do what I want it to do. Considering I would like to type erase a certain group of numeric objects (double, int, ..), and retain the possibility of assigning, calculating and comparing (again provided lhs and rhs on operators are of identical type) on them, what would be my best option? Can I do this with std::variant? In that case, I can guarantee that objects contained support those operations and just forward them to their operator. Is this feasible? – d-karl Dec 06 '18 at 14:04

1 Answers1

3

Because in full generality (which is what std::any aspires to) these operators don't make sense. With regards to your specific examples;

+: Meaningless for date-like objects.

==: Meaningless for write-only objects.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483