Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of using std::variant as opposed to traditional polymorphic processing?

Suppose I have a Shape base class and Circle, Line, and Point derived classes. I have two functions.

std::variant<Circle, Line, Point> process(const Shape &s);
Shape process(const Shape& s);

I can pass in any of my derived classes and return a Shape object in the second function, a variant is just a union that can hold any of my derived class variables at any given time.

Now with std::variant I can also employ a visitor where I can process some function depending on what type my variant is currently holding (I could just create a function object and pass it std::transform and apply it to each of my objects). However, I can just make that function virtual in my base class and have each derived class implement it.

So, is variant just a convenience?

like image 765
Mutating Algorithm Avatar asked Jan 01 '23 21:01

Mutating Algorithm


2 Answers

So, is variant just a convenience?

No, they are different concepts. Main difference that on one side std::variant can work with unrelated types including builtins like int which is not possible with virtual functions directly. On another side std::variant must know types it is working with at compile time. For example it is possible to add a type with virtual function(s) by just linking additional object module without recompiling rest of the code or loading a shared library dynamically to existing application (you do not even have to restart the app) while with std::variant you must recompile code dealing with types std::variant contains.

like image 157
Slava Avatar answered Jan 19 '23 16:01

Slava


However, I can just make that function virtual in my base class and have each derived class implement it.

Yes.... if all the elements in the variant share a common Base (which Slava already mentioned).

Another big difference is that, with a variant, there's not necessarily any dynamic polymorphism happening at all (no RTTI needed) during visitation.

In conjunction with std::visit, there are a lot of tricks under the hood to make sure that there's (basically) zero runtime overhead in calling the appropriate function for a given std::variant. Although there could be non-trivial additional compile time and memory usage because it does this by creating a big matrix of function pointers (See this excellent blog post from Michael Park about it)

like image 25
AndyG Avatar answered Jan 19 '23 15:01

AndyG