0

我正在尝试创建一个具有字符串标签和值的 Enum,并且我计划使用它从 ini 文件中读取内容。

例如,在 ini 文件中,我可能有一些double,intstringtype 值,前面有值的标记/名称:

SomeFloat = 0.5
SomeInteger = 5
FileName = ../Data/xor.csv

当我从文件中读取标签时,它以 a 的形式出现string,所以我只想让它std::set保留我的所有值......当我读取标签时,我可以将它EnumType与将检查类型并进行正确的转换(atoi 或仅使用字符串等)

例如:

EnumType<int>     someInteger;
someInteger.label = "SomeInteger";
someInteger.type = INT;

std::set<EnumType> myValues;
//
// populate the set
myValues.insert(someInteger);
//

void ProcessTagAndValue(const std::string &tag, const std::string &value)
{
    switch(myValues[tag].type)
    {
    case INT:
        myValues[tag].value = atoi(value);
        break;
    case DOUBLE:
        //
        break;
    case STRING:
        myValues[tag].value = value;
        break;
    default:
        break;
    }
}

enum ValueType{INT,DOUBLE,STRING];

template <class T>
struct EnumType{
    std::string label;
    ValueType   type;
    T           value;

    bool operator==(const EnumType &other) const {
        return this->label == other.label;
    }

    bool operator==(const T& other ) const
    {
        return this->value == other;
    }

    T& operator=(const T& p)
    {
        value = p;
        return value;
    }

    EnumType& operator=(const EnumType& p)
    {
        if (this != &p) {  // make sure not same object
            this->label = p.label;
            this->value = p.value;
        }
        return *this;
    }
};

我有几个问题:

  1. 你们能告诉我更好的解决方案吗?我不确定我是否为了我自己的利益而过于聪明,或者这是否真的是一个可行的解决方案。

  2. 如果我的解决方案是可以接受的,那么任何人都可以告诉我如何声明一组,std::set<EnumType<...>>以便它可以接受任何类型(int、double、string),而我实际上并不知道枚举将使用哪种类型作为值?

如果您有任何代码,那就太好了!:)

4

2 回答 2

1

你看过Boost.Any吗?它应该做你想做的(如果你需要自己动手,你可以查看源代码以获取提示)。

于 2009-05-12T22:16:13.810 回答
1

如果您的类型集有限且非常稳定,则可以使用Boost.Variant 。如果您稍后要添加对新类型的支持,那么最好忘记此方法。在这种情况下,基于Boost.Any或一对字符串的解决方案会更好。

typedef boost::variant<int, double, std::string> ValueType;
struct EnumType {
std::string label;
ValueType value;
};

另一个问题是:“这些值以后将如何使用?” 如果您要将“SomeInteger”传递给函数,接受 int,您仍然必须运行类似于以下内容的代码:

acceptInt( get<int>( v.value ) ); // get may throw

当您对固定类型集进行统一处理时,此方法效果更好:

class processValue : public boost::static_visitor<>
{
public:
    void operator()(int i) const
    {
        acceptInt( i );
    }
    void operator()(double d) const
    {
        acceptDouble( d );
    }
    void operator()(const std::string & str) const
    {
        acceptString( str );
    }
};
boost::apply_visitor( processValue(), v.value );
于 2009-05-12T22:58:53.460 回答