如何在一个属性中动态存储基本类型?

时间:2018-07-26 09:18:43

标签: c++ arduino esp32

我对C / C ++还是很陌生,通常,我使用C#编写代码,所以我有一个问题:

enum PrimitiveType {
    BOOL,
    STRING,
    INT8,
    INT16,
    INT32,
    UINT8,
    UINT16,
    UINT32,
};


struct MyValue
{           
public:  
    String Id         
    PrimitiveType ValueType;        
    [???] Value;         
};

我想在该int属性中存储stringbool"Value"。 在C#中,我将Value声明为对象,然后将该对象转换为intbool,如:

if(myValueObject.ValueType == BOOL)
    auto value = (bool)myValueObject.ValueType;

我可以在C ++中使用哪种类型?

2 个答案:

答案 0 :(得分:5)

对此的规范答案是std::variant。但是,我将摆脱那个枚举,因为它引入了多个事实来源:

using PrimitiveValue = std::variant<bool, String, int8_t, int16_t, int32_t, uint8_t, uint16_t, uint32_t>;

struct MyValue {
    String id;
    PrimitiveValue val;
};

如果您绝对需要产生该枚举值,则需要一个映射:

PrimitiveType MyValue::getPrimitiveType() const {
    if (val.holds_alternative<bool>()) { return BOOL; }
    else if (val.holds_alternative<String>()) { return STRING; }
    else if (val.holds_alternative<int8_t>()) { return INT8; }
    // else ...
}

以这种方式进行操作可确保永远不会发生类型描述符与实际存储的值不匹配的状态,因为variant保证了这一点。

话虽这么说,在这种价值上行动的“ C#方式”并不是这里的最佳选择。更好的一个是std::visit,它与该页面上的overloaded助手一起可以生成真正简洁的代码,根据所存储的值而有所不同。

答案 1 :(得分:1)

如上所述,std::variant可能是最好的解决方案,但您需要C ++ 17。如果可以选择C ++ 17,则也可以使用std::any

如果您使用的是C ++ 17之前的版本,则我建议使用union声明。