Some time ago I wrote about a new way to implement runtime polymorphism which is based not on virtual functions but on std::visit and std::variant. Please have a look at this new blog post where I experiment with this approach on my home project. The experiment is more practical than artificial examples.

See advantages, disadvantages and practical code issues.

Intro

The new kind of runtime polymorphism is based on the fact that you can call std::visit and then - at runtime - select the best matching overload for the active type in the variant:

Here’s a code sample which summarises this technique:

Java

struct A {

    void PrintName() const { 

        std::cout << "calling A!\n"

    }

};

struct B {

    void PrintName() const { 

        std::cout << "calling B!\n"

    }

};

struct CallPrintName {

    void operator()(const A& a) { a.PrintName(); }    

    void operator()(const B& b) { b.PrintName(); }    

};

std::variant<A, B> var;

var = B{};

std::visit(CallPrintName{}, var);

// alternative (with a generic lambda):

auto callPrintName = [](const auto& obj) { obj.PrintName(); };

std::visit(callPrintName, var);

As you can see, we have two classes (unrelated, with just a similar member function name) and we “pack” them into a single std::variant which can represent the first or the second type. Then when we want to call a given member function, we need to create a function object which handles both types (we can also create a generic lambda).

What are the advantages?

  • No dynamic allocation to create a polymorphic class
  • Value semantics, variant can be easily copied
  • Easy to add a new “method”, you have to implement a new callable structure. No need to change the implementation of classes
  • There’s no need for a base class, classes can be unrelated
  • Duck typing: while virtual functions need to have the same signatures, it’s not the case when you call functions from the visitor. They might have a different number of argument, return types, etc. So that gives extra flexibility.

You can read more in: Bartek’s coding blog: Runtime Polymorphism with std::variant and std::visit

Let’s try to implement this approach on my project, is this as easy as it sounds on an artificial example?

#tutorial #iot #software development #c++ #visual c++ #opengl #shaders #vc++ #glsl

Replacing Unique_ptr With C++17's std::variant — a Practical Experiment
1.50 GEEK