2017-01-01 61 views
0

我正在写一个需要存储一堆不同的基元和类的类。我决定为每种不同的数据类型创建一个映射,其中映射中的键将是变量的名称,而映射中的值将是变量的值。我的地图是这样定义的:是否有合并或简化这些STL映射的好方法?

std::unordered_map<std::string, int> myInts; 
std::unordered_map<std::string, float> myFloats; 
std::unordered_map<std::string, Something> mySomethings; 

对于每一个地图,我必须写两个方法,其中之一会得到一些变量的值和一个将设置一些变量的值,像这样:

void setMyInt(const std::string &varName, int newVal) { 
    myInts[varName] = newVal; 
} 
int getMyInt(const std::string &varName) { 
    return myInts[varName]; 
} 

这样很好很容易,但是,我结束了8个不同的地图,其中16个获得设置方法。这对我来说似乎不是很有效率或者干净,更不用说每次我需要存储一个新的数据类型时,我都必须定义一个新的映射并编写2个新的get-set方法。

我认为摆脱了get set方法,而是编写了2个模板方法,它们将采用用户需要获取或设置的变量类型,然后访问正确的集合以执行操作,如下所示:

template<class Type> 
void getVariable<Type>(const std::string &varName) { 
    // if Type == int -> return myInts[varName]; 
    // else if Type == float -> return myFloats[varName]; 
} 

这似乎是因为用户一个真正的穷人的办法可以通过在不被支持的类类型和方法突破不是真正通用的C++的规则。

我的另一个想法是写一些变量类,它将拥有该类应该存储的所有字段,以及一些枚举,该变量定义了该类实际正在使用的变量,然后创建此变量的映射类是这样的:

enum Type { 
    TYPE_INT, 
    TYPE_FLOAT, 
    TYPE_SOMETHING 

class Variable { 
    Type type; 

    int myInt; 
    float myFloat; 
    Something mySomething; 
} 
std::unordered_map<std::string, Variable> myVariables; 

但是,这也似乎是一个真正的穷人的解决方案,或至少其中一个是很难理解。有没有一些聪明的方式来使这个类商店不同类型?

+0

*这似乎是一个非常糟糕的方法,因为用户可以传入类中不支持的类型* - 您可以使用[编译时断言](http://en.cppreference.com/w/) cpp/language/static_assert)停止,如果不支持类型则会出现编译错误。另外,你的'get'方法使用'[]'来检索该项目。请注意,如果关键项不存在,map的'[]'会插入一个新项目。这是你真正想做的吗? – PaulMcKenzie

+2

您是否在寻找['std :: variant'](http://en.cppreference.com/w/cpp/utility/variant)?你的'Variable'似乎是一个重新尝试'std :: variant'的尝试。就我个人而言,这是我首先想到的方法。 –

+0

@PaulMcKenzie我试着查找限制模板只有某些类之前,人们已经建议编译时间断言,但也有人说,模板应该是真正的通用,并且这种断言打破了该规则。 – user3250889

回答

0

如何模板类象下面这样:

template<typename ValueType> 
class UnorderedStringMap : public std::unordered_map<std::string, ValueType> { 
public: 
    ... 
    void setValue(const std::string &varName, ValueType newVal) { 
    std::unordered_map::operator[](varName) = newVal; 
    } 
    const ValueType& getValue(const std::string &varName) { 
    return std::unordered_map::operator[](varName); 
    } 
    ... 
} 

UnorderedStringMap<int> myInts; 
UnorderedStringMap<float> myFloats; 

然后,您可以使用它作为一个正常的std :: unordered_map为好。

+0

我想这可能是消除所有这些get-set方法的最好方法,谢谢! – user3250889

相关问题