C ++实用程序,用于将long switch语句转换为简洁的函数调用,该函数调用封装了switch case ladder

时间:2017-08-21 06:01:15

标签: c++ c++11 templates preprocessor boost-preprocessor

我想编写一个可以执行以下操作的C ++实用程序:

当前工作流程

int num;
std::string str;
switch(num){
    case 2:
        str = "two";
    break;
    case 5:
        str = "five";
    break;
    case 7:
        str = "seven";
    break;
}

我想实现这个目标:

//key is always guaranteed to be int but value can be anything
DECLARE_SWITCH( {
    {2 , "two"},
    {5 , "five"},
    {7 , "seven"}
})

int num = 5;
std::string str;

match(num,str,ARR);
//here str == "five"

我想编写DECLARE_SWITCH并匹配函数。对语言结构没有任何限制 - 预处理器MACRO,模板可以做任何事情。但是,如果有一些简单的解决方案或技巧会很好。我知道关联数据结构,但我不想使用任何数据结构。这个问题具体是关于使用switch case。

3 个答案:

答案 0 :(得分:3)

std::map / std::unordered_map非常适合此用例。

地图是关联容器,用于存储按照特定顺序组合值和映射值形成的元素。

在您的情况下,您需要int和映射值std::string

这是一个例子

std::map<int, std::string> t;

t[1] = "one";
t[2] = "two";
t[3] = "three";

std::cout << "Value for '2': " << t[2] << std::endl;

for (auto& it : t)
{
    std::cout << it.first << ": " << it.second << std::endl;
}

for (auto& it : t)
{
    if (it.second == "one")
    {
        std::cout << "Value mapped to 'one' is: " << it.first << std::endl;
    }
}

输出

Value for '2': two
1: one
2: two
3: three
Value mapped to 'one' is: 1

在你的情况下

std::map<int, std::string> DECLARE_SWITCH
{
    {2 , "two"},
    {5 , "five"},
    {7 , "seven"}
};

int num = 2;
std::string str = DECLARE_SWITCH[num];

std::cout << str << '\n';

答案 1 :(得分:3)

使用地图,您甚至可以使代码看起来与原始样本非常相似

#include <map>
#include <string>
#include <iostream>

int main()
{
    std::map<int,std::string> DECLARE_SWITCH {
        {2 , "two"},
        {5 , "five"},
        {7 , "seven"}

    };

    int num = 5;
    std::string str = DECLARE_SWITCH[num];

    std::cout << str << '\n';
    return 0;
}

请注意,如果不存在,operator []将向映射插入新条目。 要避免此类行为,您必须使用find

#include <map>
#include <string>
#include <iostream>

std::string match(int number, const std::map<int,std::string>& DECLARE_SWITCH )
{
    auto q = DECLARE_SWITCH.find(number);
    if (q==DECLARE_SWITCH.end()) {
        return "";
    }
    else
        return q->second;
}

int main()
{
    const std::map<int,std::string> DECLARE_SWITCH {
        {2 , "two"},
        {5 , "five"},
        {7 , "seven"}
    }; //now we can declare map as const

    int num = 5;
    std::string str = match(num,DECLARE_SWITCH);

    std::cout << str << '\n';
    return 0;
}

答案 2 :(得分:0)

嗯,你正在寻找X macro

警告概念代码不是TESTET

#define LIST_OF_VARIABLES \
    X(2 , "two") \
    X(5 , "five") \
    X(7 , "seven")


template<class RetValue>
RetValue match(int key) {
    #define SWITCH(CASE, VALUE) case CASE : return VALUE; 

    #define X(PAIR) SWITCH(PAIR)

    // makes the actual switch case
    switch(key) {
      LIST_OF_VARIABLES 
      default: throw "fail";
    }
    #undef SWITCH
    #undef X
}    

int main()
    int num = 5;
    std::string str;

    str = match<std::string>(num);
    std::cout << str;
}