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

Mr.*_*eep 2 c++ arduino esp32

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

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


struct MyValue
{           
public:  
    String Id         
    PrimitiveType ValueType;        
    [???] Value;         
};
Run Code Online (Sandbox Code Playgroud)

我想将ints,strings和bools 存储在该"Value"属性中.在C#,我将宣布Value为对象和把对象到一个intbool像:

if(myValueObject.ValueType == BOOL)
    auto value = (bool)myValueObject.ValueType;
Run Code Online (Sandbox Code Playgroud)

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

Bar*_*icz 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;
};
Run Code Online (Sandbox Code Playgroud)

如果您绝对需要生成枚举值,则需要映射:

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 ...
}
Run Code Online (Sandbox Code Playgroud)

这样做可以确保可能永远不会出现类型描述符与实际存储的值不匹配的状态,因为variant保证了.

话虽这么说,你采用这种价值的"C#方式"并不是最好的选择.一个更好的一个是std::visit与该overloaded页面的帮助程序一起产生非常简洁的代码,根据存储的值,它们的行为会有所不同.