Я хочу реализовать вариантный класс, который может хранить любой тип данных (например, boost :: any), но с поддержкой преобразования типов данных.Например,
Variant v1(int(23)); can be converted to bool via v1.get<bool>()
using Conv<int, bool>, Variant v2(CustomT1()); to CustomT2
via Conv<CustomT1, CustomT2> and so on.
Вот текущая реализация, основанная на идее boost :: any:
#include <iostream>
#include <string>
#include <memory>
#include <stdexcept>
template<typename Src, typename Dest>
struct Conv
{
/* static? */ Dest convert(const Src& src) const { throw std::runtime_error("type cast not supported"); }
};
template<> struct Conv<int, bool>
{
bool convert(const int &src) const { return src > 0; }
};
class IStoredVariant
{};
template<typename T>
struct variant_storage : public IStoredVariant
{
variant_storage(const T& value) : m_value(value)
{}
T& getValue(void) { return this->m_value; }
const T& getValue(void) const { return this->m_value; }
template<typename U>
U make_conversion(void) const // just an idea...
{
return Conv<U, T>().convert(this->getValue());
}
protected:
T m_value;
};
class Variant
{
public:
template<typename T>
Variant(const T& value) : m_storage(new variant_storage<T>(value))
{}
IStoredVariant& getImpl(void) { return *this->m_storage; }
const IStoredVariant& getImpl(void) const { return *this->m_storage; }
std::auto_ptr<IStoredVariant> m_storage;
template<typename T>
T get(void) const
{
const IStoredVariant &var = this->getImpl();
// ????????????
// How to perform conversion?
}
template<typename T>
void set(const T &value)
{
this->m_storage.reset(new variant_storage<T>(value));
}
};
int main(void)
{
Variant v(int(23));
bool i = v.get<bool>();
}
Из метода шаблона get <> у меня есть доступ только куказатель IStoredVariant, но мне нужно знать конкретный тип, чтобы выбрать конвертер <>.Есть ли какой-либо шаблон проектирования или обходной путь для решения этой проблемы?