A few days ago I wrote a simple alternative to std::any
. It is heavily inspired by Sean Parent’s talk
Better Code: Runtime Polymorphism.
If you don’t know what std::any
is, basically it is a structure that can hold data of any type,
while maintaining the value semantics.
With C++11 this is really easily done in just a few lines. I’m still unsure how and where can I use it.
// "struct object" is the magic type.
// Basically "object" holds a pointer to "object_storage_interface".
//
// This "object_storage_interface" basically holds the *actual data*
// and provides a few methods used for communication
// between the data and the "srtuct object".
#include <iostream>
#include <memory>
#include <string>
#include <vector>
struct object_storage_interface
{
object_storage_interface() {}
virtual ~object_storage_interface() = default;
virtual std::unique_ptr<object_storage_interface> createACopy() const = 0;
};
template<typename T>
struct Tobject_storage : public object_storage_interface
{
Tobject_storage() = default;
Tobject_storage(T v) :
m_value(std::move(v))
{}
std::unique_ptr<object_storage_interface> createACopy() const override
{
return std::make_unique<Tobject_storage>(m_value);
}
T m_value;
};
struct object
{
object() = default;
template <typename T>
object(const T& ref) :
m_storage(std::make_unique<Tobject_storage<T>>(std::move(ref)))
{ }
object(const object& ref) :
m_storage(ref.m_storage ? ref.m_storage->createACopy() : nullptr)
{}
object(object&&) noexcept = default; // noexcept ...
object& operator=(const object& ref)
{
m_storage = ref.m_storage ? ref.m_storage->createACopy() : nullptr;
return *this;
}
private :
std::unique_ptr<object_storage_interface> m_storage;
};
int main()
{
std::vector<object> objects;
object a = 5;
object b = std::string("123");
object x = b;
x = a;
objects.emplace_back(a);
objects.emplace_back(b);
objects.emplace_back(x);
return 0;
}