一个std :: pair的switch语句?

问题描述 投票:2回答:2

我想切换两个整数的可能值,或者在另一种情况下切换两个bool。为了便于讨论,假设我已经完成了

auto mypair = std::make_pair(foo, bar);

我怎样才能达到相当于

switch(mypair) {
case make_pair(true, false): cout << "true and false"; break;
case make_pair(false, true)  cout << "false and true"; break;
case default: cout << "something else";
}

用C ++ 11? (如果有帮助,C ++ 14/17也相关)?

c++11 switch-statement pattern-matching
2个回答
2
投票

C ++的switch语句没有许多其他语言的模式匹配能力。你需要采取略微不同的方法。

这是我扔在一起的可能性:

pair_switch(my_pair,
    std::make_tuple(true, false, []{ std::cout << "true and false"; }),
    std::make_tuple(false, true, []{ std::cout << "false and true"; }));

你提供std::pair<bool,bool>和一组case作为std::tuples,其中前两个元素匹配你传入的对,第三个元素是调用该情况的函数。

该实现有一些模板技巧,但应该是非常有用的:

template <typename... Ts>
void pair_switch(std::pair<bool,bool> pair, Ts&&... ts) {
    //A table for the cases
    std::array<std::function<void()>, 4> table {};

    //Fill in the cases
    (void)std::initializer_list<int> {
        (table[std::get<0>(ts)*2 + std::get<1>(ts)] = std::get<2>(ts), 0)...
    };

    //Get the function to call out of the table
    auto& func = table[pair.first*2 + pair.second];

    //If there is a function there, call it
    if (func) {
        func();   
    //Otherwise, throw an exception
    } else {
        throw std::runtime_error("No such case");   
    }
}

Live Demo


1
投票

您只能打开一个整数类型,但如果您可以设计一个函数来将您的对(或任何复杂类型)映射到整数类型,您可以将其声明为constexpr(C ++ 11)以指示它可以在编译时间。然后作为案例表达是可以接受的。

简单的例子:

enum Action { peel, eat, juice };
enum Fruit { apple, orange, banana };

constexpr unsigned int switch_pair(Action a, Fruit f) {
   return (a << 16) + f;
}

然后像这样定义开关:

switch(switch_pair(mypair.first,mypair.second))
{
   case switch_pair(peel,apple):  std::cout << "Peeling an apple" << std::endl; break;
   case switch_pair(eat,apple):   std::cout << "Eating an apple" << std::endl; break;
   case switch_pair(juice,apple): std::cout << "Juicing an apple" << std::endl; break;
   default:
      throw std::runtime_error("We only have apples!");
}
© www.soinside.com 2019 - 2024. All rights reserved.