有没有一种更干净的方法可以在c++(11)中复制具有多类型值的无序映射
Is there a cleaner way to replicate an unordered_map with multi-type values in c++(11)
基本思想是获得一个存储不同类型值的无序映射。我想做的是创建一个易于访问的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类中,我有重载运算符[]:
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::数组类型。还请注意,我正在使用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。
boost::variant
或boost::any
。
如果你不能或不想使用boost,请阅读他们做了什么。
我会自己去variant
。
绝对提升::变体。这就是它的初衷。下面是一个使用代码的小示例:
#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 };
}
如果您想要在不键入std::vector<float>
等的情况下使用{ 0.1f, 0.1f, 0.0f }
语法,则可能需要某种类型的代理来处理初始值设定项列表。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 有没有一种更干净的方法可以在c++(11)中复制具有多类型值的无序映射