Skip to content

Instantly share code, notes, and snippets.

@vladiant
Last active December 18, 2020 14:53
Show Gist options
  • Save vladiant/7de39543644419bfeca5425952932de9 to your computer and use it in GitHub Desktop.
Save vladiant/7de39543644419bfeca5425952932de9 to your computer and use it in GitHub Desktop.
Meta Polymorphism - Jonathan Boccara - Meeting C++ 2020 Opening Keynote
// Example program
#include <any>
#include <iostream>
#include <vector>
struct Interface {
virtual void draw() const = 0;
virtual ~Interface() = default;
};
struct Square : Interface {
void draw() const override { std::cout << "Draw Square\n"; }
};
struct LightningBolt : Interface {
void draw() const override { std::cout << "Draw LightningBolt\n"; }
};
// Wrapper with value semantics
// Not nullable unlike unique_ptr
// using Shape = Implementation<IShape>
class Implementation {
public:
template <typename ConcreteImplementation>
Implementation(ConcreteImplementation&& Implementation)
: storage{std::forward<ConcreteImplementation>(Implementation)},
getter{[](std::any& storage) -> Interface& {
return std::any_cast<ConcreteImplementation&>(storage);
}} {}
Interface* operator->() { return &getter(storage); }
private:
std::any storage;
Interface& (*getter)(std::any&);
};
Implementation createImplementation() { return Square{}; }
int main() {
createImplementation()->draw();
std::vector<Implementation> Implementations;
Implementations.push_back(Square{});
Implementations.push_back(LightningBolt{});
Implementations[0]->draw();
Implementations[1]->draw();
return 0;
}
// Example program
#include <variant>
#include <iostream>
#include <vector>
struct Square {
void draw() const { std::cout << "Draw Square\n"; }
};
struct LightningBolt {
void draw() const { std::cout << "Draw LightningBolt\n"; }
};
using Shape = std::variant<Square, LightningBolt>;
// template<typename... Functions>
// struct overload : Functions...
// {
// using Functions::operator()...;
// overload(Functions... functions) : Functions(functions)...{}
// };
void draw(Shape const& shape) {
// std::visit(overload(
// [](Square const& square){square.draw();},
// [](LightningBolt const& lightningBolt){lightningBolt.draw();}
// ),
// shape);
std::visit([](auto&& shape){ shape.draw();}, shape);
}
int main() {
Square test1;
draw(test1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment