我正在尝试检索存储在具有变体类型的返回变量中的值,但我正在努力使其工作。你有什么想法? :)
我几乎尝试了所有方法,包括模板和指针,但没有成功。出现这个问题是因为 getValue 函数的输出变量类型取决于存储的变体类型。
这是当前错误: 错误 C2338 Visit() 要求所有潜在调用的结果具有相同的类型和值类别 (N4835 [variant.visit]/2)
问题2:如何使variant中的char类型工作? (注释掉的部分)
#include <iostream>
#include <variant>
#include <string>
// Note: platform dependent type sizes
typedef unsigned char uint8;
typedef signed char sint8;
typedef unsigned short uint16;
typedef signed short sint16;
typedef unsigned long uint32;
typedef signed long sint32;
typedef unsigned long long uint64;
typedef signed long long sint64;
typedef uint8 boolean;
typedef std::string SignalName;
typedef std::string SignalType;
// Define enum for signal types
enum class SignalTypeEnum {
Double,
UInt8,
SInt8,
UInt16,
SInt16,
UInt32,
SInt32,
UInt64,
SInt64,
Boolean,
Int,
Bool
};
// Define a map from string to SignalTypeEnum
SignalTypeEnum getSignalType(const SignalType& type) {
if (type == "double") return SignalTypeEnum::Double;
if (type == "uint8") return SignalTypeEnum::UInt8;
if (type == "sint8") return SignalTypeEnum::SInt8;
if (type == "uint16") return SignalTypeEnum::UInt16;
if (type == "sint16") return SignalTypeEnum::SInt16;
if (type == "uint32") return SignalTypeEnum::UInt32;
if (type == "sint32") return SignalTypeEnum::SInt32;
if (type == "uint64") return SignalTypeEnum::UInt64;
if (type == "sint64") return SignalTypeEnum::SInt64;
if (type == "boolean") return SignalTypeEnum::Boolean;
if (type == "int") return SignalTypeEnum::Int;
if (type == "bool") return SignalTypeEnum::Bool;
// Default to Boolean if type is unrecognized
return SignalTypeEnum::Double;
}
typedef std::variant<double, uint8, sint8, uint16, sint16, uint32, sint32, uint64, sint64, boolean, int, bool> SignalValue;
class ValueItem {
protected:
SignalName name;
SignalType type;
SignalValue value;
bool isValid() {
// TODO: Implement validation logic
return true;
}
public:
ValueItem(SignalName name = "", SignalType type = "", SignalValue value = 0)
: name(name), type(type), value(value) {}
SignalName getName() const {
return name;
}
SignalType getType() const {
return type;
}
SignalValue getValue() const {
SignalTypeEnum signalType = getSignalType(type);
//auto tmp_2 = std::get<bool>(value);
switch (signalType) {
case SignalTypeEnum::Double:
return std::get<0>(value);
//case SignalTypeEnum::UInt8: return std::get<1>(value);
case SignalTypeEnum::SInt8:
return std::get<2>(value);
case SignalTypeEnum::UInt16:
return std::get<3>(value);
case SignalTypeEnum::SInt16:
return std::get<4>(value);
case SignalTypeEnum::UInt32:
return std::get<5>(value);
case SignalTypeEnum::SInt32:
return std::get<6>(value);
case SignalTypeEnum::UInt64:
return std::get<7>(value);
case SignalTypeEnum::SInt64:
return std::get<8>(value);
//case SignalTypeEnum::Boolean: return std::get<9>(value);
case SignalTypeEnum::Int:
return std::get<10>(value);
case SignalTypeEnum::Bool:
return std::get<11>(value);
default:
return std::get<double>(value);
}
}
void setValue(SignalType type, SignalValue value) {
this->type = type;
this->value = value;
if (!isValid()) {
// TODO: Report the error
}
}
void setName(SignalName name) {
this->name = name;
}
};
int main() {
ValueItem item;
item.setValue("bool", false); // Now using SignalTypeEnum instead of string
auto value_output = item.getValue();
int index = value_output.index();
auto result = std::visit([](auto v) -> decltype(v) { return v; }, value_output);
}
必须有一个从传递给
std::visit
的访问者函数返回的单一类型。如果您想做一些取决于值类型的事情,则必须在访问者内部进行。
注意:你的
getValue
是做 return value
的一种非常迂回的方式,但如果 isValid
为 false,则有例外。您不需要在变体旁边携带类型,它会为您做到这一点。
class ValueItem {
private:
SignalName name;
SignalValue value;
public:
ValueItem(SignalName name = "", SignalValue value = 0)
: name(name), value(value) {}
SignalName getName() const {
return name;
}
void setName(SignalName name) {
this->name = name;
}
SignalType getType() const {
switch (value.index()) {
case 0: return "double";
case 1: return "uint8";
case 2: return "sint8";
case 3: return "uint16";
case 4: return "sint16";
case 5: return "uint32";
case 6: return "sint32";
case 7: return "uint64";
case 8: return "sint64";
case 9: return "boolean";
case 10: return "int";
case 11: return "bool";
default: throw std::bad_variant_access();
}
}
SignalValue getValue() const {
return value;
}
void setValue(SignalValue value) {
this->value = value;
}
};
int main() {
ValueItem item("", false);
std::visit([](auto result) -> void { /* do stuff with result */ }, item.getValue());
}