2

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

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


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

我想在该属性中存储ints、strings 和s。在 C# 中,我将声明为对象并将对象转换为或类似:bool"Value"Valueintbool

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

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

4

2 回答 2

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可以生成非常简洁的代码,根据存储的值执行不同的操作。

于 2018-07-26T09:26:07.260 回答
1

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

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

于 2018-07-26T09:41:57.443 回答