C++ 是否有一种更干净的方法可以在c+中复制具有多类型值的无序#u映射+;(11)
基本思想是获得一个无序的_映射,该映射存储不同类型的值。我试图做的是为OpenGL统一缓冲区对象创建一个易于访问的对象。最终产品看起来像:C++ 是否有一种更干净的方法可以在c+中复制具有多类型值的无序#u映射+;(11),c++,types,unordered-map,C++,Types,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
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类中,我有重载运算符[]:
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];
}
};
我已经截断了这个示例中的类型,没有std::array类型。还请注意,我正在使用一个空*来存储值,并告诉我需要重新思考我的设计。我当然会,这就是我来这里的原因:)
我试图用类型检查来包装void*,但是有没有更好的方法来获得没有void*的多类型映射
注意:我在Windows上使用VS2013,在Mac和Linux上使用clang。
boost::variant
或boost::any
如果您不能或不想使用boost,请阅读他们所做的
我会自己选择变体。当然。这就是它建造的目的。以下是使用您的代码的示例:
#include <unordered_map>
#include <vector>
#include <boost/variant.hpp>
class UBO
{
using UBOData = boost::variant<float, std::vector<float>>;
std::unordered_map<std::string, UBOData> dataMap;
public:
UBO() : dataMap(){}
UBOData &operator[](const std::string& key)
{
return dataMap[key];
}
};
int main()
{
UBO ubo;
ubo["scale"] = 0.5f;
ubo["translation"] = std::vector<float>{ 0.1f, 0.1f, 0.0f };
ubo["rotation"] = std::vector<float>{ 90.0f, 0.0f, 0.0f, 1.0f };
}
#包括
#包括
#包括
UBO类
{
使用UBOData=boost::variant;
std::无序地图数据地图;
公众:
UBO():数据映射(){}
UBOData和运算符[](常量标准::字符串和键)
{
返回数据映射[键];
}
};
int main()
{
UBO UBO;
ubo[“刻度”]=0.5f;
ubo[“translation”]=std::vector{0.1f,0.1f,0.0f};
ubo[“旋转”]=标准::向量{90.0f,0.0f,0.0f,1.0f};
}
如果您想要
{0.1f,0.1f,0.0f}
语法而不键入std::vector
等,您可能需要某种类型的代理来处理初始值设定项列表。您是否考虑过使用类型的多态层次结构,存储指向基类的(智能)指针?然后,您可以通过让映射在每个元素上调用clone()
方法来“复制”(copy)映射。或者,你可以考虑Boost变体或者Boost。这让我找到了这个链接:与您的问题无关:您的操作符[]
的常量版本根本不是常量。这没有道理。@c.r.看起来像是试图使用非const
版本,但失败得很惨。@c.r.你说得对。这是一个复制粘贴错误。谢谢。是的,从上面TonyD的评论中我看到了这两种结构。我还发现了另一个与这个主题相关的链接,其中有一个有趣的花絮,谢谢。我将进一步研究boost变体。boost::variant可以接受两个以上的模板参数吗?@SethHays:可以,最多20个。
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;
}
#include <unordered_map>
#include <vector>
#include <boost/variant.hpp>
class UBO
{
using UBOData = boost::variant<float, std::vector<float>>;
std::unordered_map<std::string, UBOData> dataMap;
public:
UBO() : dataMap(){}
UBOData &operator[](const std::string& key)
{
return dataMap[key];
}
};
int main()
{
UBO ubo;
ubo["scale"] = 0.5f;
ubo["translation"] = std::vector<float>{ 0.1f, 0.1f, 0.0f };
ubo["rotation"] = std::vector<float>{ 90.0f, 0.0f, 0.0f, 1.0f };
}