Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
范围的开关语句 有一种方法在C++中编写一个转换语句,在那里处理范围。 案例0-10做一个, 案例20-40 do b, 案例40-80 do c, 等 我可以用一堆if-else-if语句写出它,但我想知道是否有更有效的方法_C++_Switch Statement_Range - Fatal编程技术网

范围的开关语句 有一种方法在C++中编写一个转换语句,在那里处理范围。 案例0-10做一个, 案例20-40 do b, 案例40-80 do c, 等 我可以用一堆if-else-if语句写出它,但我想知道是否有更有效的方法

范围的开关语句 有一种方法在C++中编写一个转换语句,在那里处理范围。 案例0-10做一个, 案例20-40 do b, 案例40-80 do c, 等 我可以用一堆if-else-if语句写出它,但我想知道是否有更有效的方法,c++,switch-statement,range,C++,Switch Statement,Range,我可以用一堆if-else-if语句写出它,但我想知道是否有更有效的方法 不,没有比这更有效的方法了。更不用说switch语句实际上不应该用于范围。您可以使用映射键来映射标准函数: #include <iostream> #include <map> #include <functional> using namespace std; int main() { std::map<int, std::function<void()>

我可以用一堆if-else-if语句写出它,但我想知道是否有更有效的方法


不,没有比这更有效的方法了。更不用说
switch
语句实际上不应该用于范围。

您可以使用映射键来映射标准函数:

#include <iostream>
#include <map>
#include <functional>

using namespace std;

int main()
{
    std::map<int, std::function<void()>> dispatcher;

    // case (-inf, 10]
    dispatcher[10] = []() {cout << 10;};
    // case (10, 50]
    dispatcher[50] = []() {cout << 50;};
    // case (50, 100]
    dispatcher[100] = []() {cout << 100;};

    (dispatcher.lower_bound(1)->second)();
    (dispatcher.lower_bound(10)->second)();
    (dispatcher.lower_bound(11)->second)();
    (dispatcher.lower_bound(50)->second)();
    (dispatcher.lower_bound(51)->second)();

   return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
地图调度器;
//案例(-inf,10]
调度程序[10]=[](){cout second()();
(调度器.下界(50)->秒)();
(dispatcher.lower_-bound(51)->second)();
返回0;
}

输出10105050100

实际上,你可以通过C中的预处理器滥用来实现这一点(虽然在C++中没有一些错误,因为C++中有一些错误,我相信有足够的毅力可以克服)。 请参见以下示例,使用:


请注意,此示例是左包含,右独占的。我相信您可以修改宏以使其符合您的要求,因此这至少是一个不错的起点。

如果您关心效率,您可以将范围映射到值,然后切换为它们:

int range_to_value(int x) 
{ 
     if (x > 0 && x < 10) return 0; 
     if (x > 20 && x < 40) return 1; 
     // ... 
} 
void switch_range(int x) 
{ 
    switch( range_to_value(x) ) 
    {
    case 0: cout << 0; break;
    case 1: cout << 1; break;
    }
 }

 switch_range(1); // output 0
 switch_range(9); // output 0
 switch_range(22); // output 1
int范围_到_值(int x)
{ 
如果(x>0&&x<10)返回0;
如果(x>20&&x<40)返回1;
// ... 
} 
无效开关_范围(整数x)
{ 
开关(范围_至_值(x))
{
案例0:cout试试这个:

case 0 ... 10:
case 20 ... 40:
case 41 ... 80:

等等

你可以一个接一个地列出多个值,但我知道没有办法有一个“范围”。也许通过一些复杂的预处理器(ab)使用它可以做到(想想看,P99有这样的宏…)我不知道用任何语言来实现这一点,更不用说C++了。通常使用开关语句来匹配精确值,而不是匹配范围。如果你想做这样的事,开关语句不是正确的结构。一般来说,当你有一组离散的可能性时,最好使用那些语句。你不想让一堆if语句把你的代码弄得乱七八糟。Pascal有这个功能。我在C及其派生语言中一直没有它。例如,手工编写扫描仪时非常有用,在编译器中实现起来也非常便宜。虽然确实很有趣,但这种方法失去了所有的性能优势(因为我不相信任何编译器都可以内联lambdas),所以我真的可以根据OP的要求推荐它。switch语句可能会更快,因为它将生成一个跳转表,而不是一系列分支。当然,这只适用于内部循环,应该在之前进行分析。@Jens,嗯。两次比较与30个条目的跳转表。你确定吗?不确定,但大小是否为f跳转表影响运行时(只要它适合缓存)?从理论上讲,为什么表中有一个或三十个跳转条目很重要?但是,预取、缓存、推测性执行、分支预测之类的事情会发生,很难说会发生什么。如果真的重要,那么必须使用良好的基准数据来衡量。每个范围有两个比较,因此if级联将运行2n com最坏情况下的型坯(检查每个if的下限和上限),而跳转表具有恒定的复杂性。
case 0 ... 10:
case 20 ... 40:
case 41 ... 80: