HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

C++11 Any class

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
anyclassstackoverflow

Problem

This is a polymorphic wrapper capable of holding any type. (It is loosely based on boost::any)

In particular, this is useful when you want to store a heterogeneous collection, such as vector.

Synopsis

string s = ...;
int i = ...;

Any a1 = s;
Any a2 = i;

int j = a2; // ok j now equals i

string t = a1; // ok t now equals s

int k = a1; // runtime exception bad_cast

vector v;

v.push_back("foo");
v.push_back(42);

const char* s = v[0];
int l = v[1];


Implementation

```
#include
#include
#include
#include
#include

using namespace std;

template
using StorageType = typename decay::type>::type;

struct Any
{
bool is_null() const { return !ptr; }
bool not_null() const { return ptr; }

template Any(U&& value)
: ptr(new Derived>(forward(value)))
{

}

template bool is() const
{
typedef StorageType T;

auto derived = dynamic_cast*> (ptr);

return derived;
}

template
StorageType& as()
{
typedef StorageType T;

auto derived = dynamic_cast*> (ptr);

if (!derived)
throw bad_cast();

return derived->value;
}

template
operator U()
{
return as>();
}

Any()
: ptr(nullptr)
{

}

Any(Any& that)
: ptr(that.clone())
{

}

Any(Any&& that)
: ptr(that.ptr)
{
that.ptr = nullptr;
}

Any(const Any& that)
: ptr(that.clone())
{

}

Any(const Any&& that)
: ptr(that.clone())
{

}

Any& operator=(const Any& a)
{
if (ptr == a.ptr)
return *this;

auto old_ptr = ptr;

ptr = a.clone();

if (old_ptr)
delete old_ptr;

return *this;
}

Any& operator=(Any&& a)
{
if (ptr == a.ptr)
return *this;

swap(ptr, a.ptr);

return *this;
}

~Any()
{
if (ptr)
delete ptr;
}

private:

Solution

template
using StorageType = typename decay::type>::type;


This appears unnecessarily complex: 'decay' already removes a reference. Consider using:

template 
using StorageType = typename decay::type;

Code Snippets

template<class T>
using StorageType = typename decay<typename remove_reference<T>::type>::type;
template <class T>
using StorageType = typename decay<T>::type;

Context

StackExchange Code Review Q#20058, answer score: 15

Revisions (0)

No revisions yet.