Основная идея - получить unordered_map, который хранит значения разных типов. То, что я пытаюсь сделать, - создать легкодоступный объект для Uniform Buffer Object OpenGL. Конечный продукт будет выглядеть примерно так:Есть ли более чистый способ репликации unordered_map с многотипными значениями в C++ (11)
UBO ubo = { "Uniforms", "translation", "scale", "rotation", "enabled" };
ubo["scale"] = 0.5f;
ubo["translation"] = { 0.1f, 0.1f, 0.0f };
ubo["rotation"] = { 90.0f, 0.0f, 0.0f, 1.0f };
ubo["enabled"] = GL_TRUE;
В моем классе УБО я перегружен оператор []:
struct UBOData;
class UBO
{
std::unordered_map<std::string,UBOData>
...
public:
UBOData &operator[](std::string key)
{
UBOData data = new UBOData();
dataMap.emplace(key, data);
return data;
}
const UBOData& operator[](std::string key)
{
return const_cast<UBOData&>(*this)[key];
}
};
И я использую UBOData для хранения различных типов данных. Именно здесь мое доверие ослабевает в свете того, что «правильно» в мире C++.
.
.
.
struct UBOData
{
enum ReturnType {Undefined, rInt, rFloat, rDouble};
void *value;
ReturnType type;
int &operator=(int lhs);
float &operator=(float lhs);
double &operator=(double lhs);
};
Я усекал типы для этого примера, без типов std :: array. Также обратите внимание, что я использую void * для хранения значения и говорю мне, что мне нужно переосмыслить мой дизайн. Конечно, я знаю, именно поэтому я здесь :)
int &UBOData::operator=(int lhs)
{
if (type == Undefined) { type = rInt; } else { assert(type == rInt); }
value = new int(lhs);
int &rValue = *((int*)value);
return rValue;
}
float &UBOData::operator=(float lhs)
{
if (type == Undefined) { type = rFloat; }
else { assert(type == rFloat); }
value = new float(lhs);
float &rValue = *((float*)value);
return rValue;
}
double &UBOData::operator=(double lhs)
{
if (type == Undefined) { type = rDouble; }
else { assert(type == rInt); }
value = new double(lhs);
double &rValue = *((double*)value);
return rValue;
}
Я попытался обернуть пустоту * с проверкой типов, но есть лучший способ, чтобы получить карту мульти-типа без пустот *?
Примечание: Я использую VS2013 для Windows и звоню на Mac и Linux.
Вы считали наличие полиморфной иерархии типов, сохраняющих (умные) указатели на базовый класс? Затем вы можете «реплицировать» (скопировать) карту, вызвав метод 'clone()' для каждого элемента. В качестве альтернативы, вы можете рассмотреть вариант повышения или увеличить любой. –
@TonyD Спасибо за предложение. Мне удалось найти эту ссылку: http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf –
Не связанный с вашим вопросом: ваша версия const 'operator []' не const at все. Это не имеет смысла. –