gpt4 book ai didi

c++ - C++ 中混合类型的容器(类似于 nsdictionary)

转载 作者:太空狗 更新时间:2023-10-29 21:08:15 24 4
gpt4 key购买 nike

我想做的(在 C++ 中)是创建一个“参数”数据类型,它有一个值、最小值和最大值。然后我想为这些类型创建一个容器。

例如我有以下代码:

    template <typename T>
class ParamT {
public:
ParamT() {
}

ParamT(T _value):value(_value) {
}

ParamT(T _value, T _vmin, T _vmax):value(_value), vmin(_vmin), vmax(_vmax) {
}


void setup(T vmin, T vmax) {
this->vmin = vmin;
this->vmax = vmax;
}

void setup(T value, T vmin, T vmax) {
setup(vmin, vmax);
setValue(value);
}

T operator=(const T & value) {
setValue(value);
}



void setValue(T v) {
value = v;
}

T getValue() {
return value;
}

operator T() {
return getValue();
}

protected:

T value;
T vmin;
T vmax;
};

typedef ParamT<int> Int;
typedef ParamT<float> Float;
typedef ParamT<bool> Bool;

在理想情况下,我的 Api 应该是这样的:

std::map<string, Param> params;
params["speed"] = PFloat(3.0f, 2.1f, 5.0f);
params["id"] = PInt(0, 1, 5);

params["speed"].setup(3.0f, 2.1f, 5.0f);
params["id"].setup(0, 1, 5);

并写信给他们:

params["speed"] = 4.2f;
params["id"] = 1;

params["speed"].setValue(4.2f);
params["id].setValue(1);

和阅读:

float speed = params["speed"];
int id = params["id"];

float speed = params["speed"].getValue();
int id = params["id"].getValue();

当然,在上面的代码中,ParamT 没有基类,所以我无法创建 map 。但是,即使我为它创建了一个 ParamT 扩展的基类,我显然也不能有不同的 getValues() 来返回不同的类型。我想了很多解决方案,包括setValueI(int i)、setValuef(float f)、int getValueI()、float getValueF(),或者ints的map,floats的map等等。但都显得很不干净。是否可以在C++中实现上述API?

目前我只关心简单的类型,如 int、float、bool 等。但我想将其扩展到 vector (我自己的),并可能更多。

最佳答案

如您所见,这是一个很难用 C++ 实现的概念。我一直支持使用 Boost 库,它有 already solved it for you .您可以将复杂的 boost 变体模板类定义为在您的特定域中更有用的东西,所以

typedef boost::variant< int, float, bool > ParamT; 
class Param
{
public:
// initialize the variants
Param(ParamT min, ParamT max, ParamT value)
: m_Min(min), m_Max(max), m_Value(value) {}

// example accessor
template<typename OutT>
const ParamT& value()
{
return boost::get<OutT>(m_Value);
}
// other accessors for min, max ...
private:
ParamT m_Min, m_Value, m_Max;
};



Param speed(-10.0f, 10.0f, 0.0f);
float speedValue = speed.value<float>();

现在,要将另一种类型添加到您的变体(例如,long、std::string 等),您只需修改 ParamT 的 typedef;这里要注意的是,检查类型的负担在你身上 - 如果你存储一个 float 并尝试接收一个 int,它会抛出异常,但没有编译时安全。

如果你真的想变得疯狂,你可以在代理对象上实现一个重载的转换运算符....

class ProxyValue
{
public:
ProxyValue(ParamT& value) : m_Value(value) {}
template<typename ValueT>
operator ValueT()
{
return boost::get<ValueT>(m_Value);
}
private:
ParamT& m_Value;
};

您将从 Param 中的非模板化 value() 函数返回 this,而不是变体本身。现在你可以在没有模板调用的情况下分配一个值..

Param speed(-10.0f, 0, 10);
float speedValue = speed.value();

虽然公平警告,但您正在步入元编程 hell 。这里有龙。和往常一样,这不是一个完整的解决方案,只是一个指针。 YMMV.

Heres a roughly working version showing how to use it, and the failures that are easy to hit.

关于c++ - C++ 中混合类型的容器(类似于 nsdictionary),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3535024/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com