Skip to content

sean parent's approach #3

@azadkuh

Description

@azadkuh

runtime polymorphism
the new struct X can store any type with void process() as method, also:

  • no inheritance is required (X0,X1,X2)
  • value semantics
  • no coupling

online code

#include <iostream>
#include <string>
#include <memory>

struct X final {
    template <typename V>
    X& operator=(V v) {
        pimpl = std::make_unique<model_t<V>>(std::move(v));
        return *this;
    }
    void process() { pimpl->process(); }

   private:
    struct concept_t {
        virtual ~concept_t() = default;
        virtual void process() = 0;
    };
    template <typename V>
    struct model_t final : concept_t {
        V value;
        explicit model_t(V v) : value{std::move(v)} {}
        void process() override { value.process(); }
    };
    std::unique_ptr<concept_t> pimpl;
};

struct X0 final {
    X0() { std::cout << "X0::X0 "; }
    ~X0() { std::cout << "\tX0::~X0\n"; }
    void process() { std::cout << "X0::Process: " << c_; }
    char c_ = 'A';
};

struct X1 final {
    X1() { std::cout << "X1::X1 "; }
    ~X1() { std::cout << "\tX1::~X1\n"; }
    void process() { std::cout << "X1::Process: " << s_; }
    std::string s_ = "ABC";
};

struct X2 final {
    X2() { std::cout << "X2::X2 "; }
    ~X2() { std::cout << "\tX2::~X2\n"; }
    void process() { std::cout << "X2::Process: " << i_; }
    int i_ = 123;
};

int main() {
    for (auto i = 0; i < 3; i++) {
        X x;
        if (i == 0)
            x = X0{};
        else if (i == 1)
            x = X1{};
        else
            x = X2{};
        x.process();
    }

    return 0;
}

static_assert(std::is_move_constructible<X>::value,  "");
static_assert(std::is_move_assignable<X>::value,     "");
static_assert(std::is_move_constructible<X0>::value, "");
static_assert(std::is_move_assignable<X0>::value,    "");

also a simple functional or CRTP approach lead to much easier (more performant) implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions