#ifndef AAB #define AAB #include <functional> #include <iostream> #include <memory> using namespace std; struct Trait { public: Trait(const Trait &trait) = default; Trait(Trait &&trait) = default; Trait &operator=(const Trait &trait) = default; Trait &operator=(Trait &&trait) = default; virtual ~Trait() = default; template <typename T> explicit Trait(T t) : container(std::make_shared<Model<T>>(std::move(t))) { } template <typename T> T cast() { auto typed_container = std::static_pointer_cast<const Model<T>>(container); return typed_container->m_data; } private: struct Concept { // All need to be explicitly defined just to make the destructor virtual Concept() = default; Concept(const Concept &concept) = default; Concept(Concept &&concept) = default; Concept &operator=(const Concept &concept) = default; Concept &operator=(Concept &&concept) = default; virtual ~Concept() = default; }; template <typename T> struct Model : public Concept { Model(T x) : m_data(move(x)) { } T m_data; }; std::shared_ptr<const Concept> container; }; #endif