【发布时间】:2013-11-20 02:30:33
【问题描述】:
基本思想是得到一个存储不同类型值的unordered_map。我要做的是为 OpenGL 统一缓冲区对象创建一个易于访问的对象。最终产品看起来像:
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;
在我的 UBO 类中,我重载了 operator[]:
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;
}
我试图用类型检查来包装 void*,但有没有更好的方法来获得没有 void * 的多类型映射?
注意:我在 Windows 上使用 VS2013,在 Mac 和 Linux 上使用 clang。
【问题讨论】:
-
您是否考虑过拥有类型的多态层次结构,存储(智能)指向基类的指针?然后,您可以通过在每个元素上调用
clone()方法来“复制”(复制)地图。或者,您可以考虑 boost 变体或 boost any。 -
@TonyD 感谢您的建议。它引导我找到这个链接:two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf
-
与您的问题无关:您的
operator []的 const 版本根本不是 const 。这没有意义。 -
@c.r.看起来像是尝试使用失败的非
const版本。 -
@C.R.你说的对。那是复制粘贴错误。谢谢。
标签: c++ types unordered-map