每个项目具有下标运算符功能的3项元组的容器

时间:2014-05-08 19:11:06

标签: c++ tuples

我有以下问题:

在某些遗留代码的某个位置是单选按钮的ID列表。在另一个地方是一组相应的字符串。在另一个地方是具有相应值的枚举。是否有任何聪明的方法可以将所有三个值组合起来,以获得类似伪代码的内容:

corresponding_enum1 = Container.IDs[id1].enum_value
corresponding_string1 = Container.IDs[id1].string_value

corresponding_id2 = Container.Enums[enum].id_value
corresponding_string2 = Container.Enums[enum].string_value

到目前为止我所得到的只是:

std::string my_strings[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
const int my_array[3][10] = 
{
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, // indexes
    {108, 106, 167, 123, 111, 168, 136, 104, 126, 194}, // enums
    {291, 275, 265, 201, 293, 244, 200, 248, 234, 285} // IDs
};

std::map<int, std::pair<int, int>> mapIndex;
std::map<int, std::pair<int, int>> mapEnum;
std::map<int, std::pair<int, int>> mapID;

for (int i = 0; i < 10; ++i)
{
    mapIndex[my_array[0][i]] = std::make_pair(my_array[1][i], my_array[2][i]);
    mapEnum[my_array[1][i]] = std::make_pair(my_array[0][i], my_array[2][i]);
    mapID[my_array[2][i]] = std::make_pair(my_array[0][i], my_array[1][i]);
}

int query = 244;
std::cout << "Id = " << query << "\t Index = " << mapID[query].first << "\t Enum" << mapID[query].second << "\n";

但我认为这是更好的方法。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我在这里做的并不是你自己的代码,它只是捆绑有关的信息 所有项目(单选按钮)很好,错误放置的可能性较小(很清楚哪些 butto ID连接到哪个枚举)。添加或删除按钮仅在a中进行更改 单个地方,宏文本文件。来源不受影响。如果从某些文档中提取信息(我使用这种技术来编写PCL6解析器,将标记映射到纸张名称,如&#34; A4&#34;纸张尺寸等),文本文件有可能自动生产(半)。顺便说一句,我认为&#34;指数&#34;对于以后的项目可能不是连续的,或者它可能被省略,因为&#34; enoms&#34;将自动成为索引序列。

编辑:重新阅读您的问题我注意到您谈到遗留代码。我的解决方案显然取决于您是否能够更改该代码(即将示例中的数组定义更改为macro-enums.txt中的格式)。

宏enums.txt:

//       name, index, enum, id
MY_MACRO(zero,  0,   108,   291)
MY_MACRO(one,   1,   106,   167)
MY_MACRO(two,   2,   167,   265)

宏enums.cpp:

#include <map>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    map<int, int> idMap;    // index -> id
    map<int, int> enumMap;  // index -> enum 
    map<int, const char *> nameMap;  // index -> "name" 
    map<const char *, int> indexMap; // "name" -> index
    // possibly other mappings

    // First let's define symbolic constants one, two etc. 
    // for the indexes. The last enum element will have a trailing
    // comma which is allowed in order to 
    // simplify exactly this kind of code generation.
#   define MY_MACRO(name, index, enom, id) name = index,
    enum indexEnumE 
    {
#       include "macro-enums.txt"   
    };

#   undef MY_MACRO

    // an enum with names like id_of_one 
    // with the corresponding id as value. 
    // Similarily doable for other
    // attributes of a button as needed. Uses the 
    // preprocessor concatenation operator ##.
#   define MY_MACRO(name, index, enom, id) id_of_##name = id,
    enum idEnumE 
    {
#       include "macro-enums.txt"   
    };

#   undef MY_MACRO

    // now let's define a map index -> id, index -> enum, 
    // index -> "name" and "name"->index
#   define MY_MACRO(name, index, enom, id) \
    idMap[index] = id; \
    enumMap[index] = enom; \
    nameMap[index] = #name; \
    indexMap[#name] = index;
    // possibly other mappings

#   include "macro-enums.txt"   

#   undef MY_MACRO

    /////////// example use /////////////
    int ind = 2;
    cout << "The enum of index " << ind << " is "
        << enumMap[ind] << endl;

    const char *name = "one";

    cout << "The index of name \"" << name << "\" is "
        << indexMap[name] << endl;

    if( idMap[zero] == id_of_zero ) 
    {
        cout << "The id enum of \"" <<  nameMap[zero]
            << "\" is as expected " << id_of_zero << endl;
    }
    else 
    {
        cout << "Internal error: The id enum of \"" << nameMap[zero] 
            << "\" unexpectedly is " << id_of_zero 
            << " but should be " << idMap[zero] << endl;
    }
}

输出:

$ ./macro-enums The enum of index 2 is 167 The index of name "one" is 1 The id enum of "zero" is as expected 291