std::variant 函数中的多个返回类型

问题描述 投票:0回答:1

我正在尝试检索存储在具有变体类型的返回变量中的值,但我正在努力使其工作。你有什么想法? :)

我几乎尝试了所有方法,包括模板和指针,但没有成功。出现这个问题是因为 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);
}
c++17 variant
1个回答
0
投票

必须有一个从传递给

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());
}
© www.soinside.com 2019 - 2024. All rights reserved.