有没有一种方法可以在多个条件下分支而不编写看起来一团糟的代码? C++11 或 C++14 中的语法糖将不胜感激。
#include <iostream>
enum state
{
STATE_1,
STATE_2,
STATE_3,
STATE_4,
STATE_5,
STATE_6,
STATE_7,
STATE_8,
};
state f(int a, bool b, const std::string& str)
{
// How not to:
if (a < 0)
{
if (b == false)
{
if (str != "morning")
{
return STATE_1;
}
else
{
return STATE_2;
}
}
else
{
if (str != "morning")
{
return STATE_3;
}
else
{
return STATE_4;
}
}
}
else // a >= 0
{
if (b == false)
{
if (str != "morning")
{
return STATE_5;
}
else
{
return STATE_6;
}
}
else
{
if (str != "morning")
{
return STATE_7;
}
else
{
return STATE_8;
}
}
}
}
int main()
{
std::cout << "State: " << f(1, true, "morning") << std::endl;
}
最佳答案
可以在编译时在 POD 中嵌入一个 bool 值(条件结果)列表,然后在其上切换
。
用法:main.cpp
#include <iostream> /* std::cout */
#include "mswitch.h" /* mswitch, mcase */
enum state
{
STATE_1,
STATE_2,
STATE_3,
STATE_4,
STATE_5,
STATE_6,
STATE_7,
STATE_8,
};
state f(int a, bool b, const std::string& str)
{
mswitch(a >= 0, b == true, str == "morning")
{
mcase(false, false, false): return STATE_1;
mcase(false, false, true) : return STATE_2;
mcase(false, true, false) : return STATE_3;
mcase(false, true, true) : return STATE_4;
mcase(true, false, false) : return STATE_5;
mcase(true, false, true) : return STATE_6;
mcase(true, true, false) : return STATE_7;
mcase(true, true, true) : return STATE_8;
}
return STATE_1;
}
int main()
{
std::cout << "State: " << f(1, true, "morning") << std::endl;
}
语法糖:mswitch.h
#ifndef MSWITCH_GUARD_H
#define MSWITCH_GUARD_H
#include <initializer_list>
#include <cstddef>
namespace mswitch
{
constexpr long long encode(long long value, size_t size) { return value << 6 | (0x3F & size); }
class mswitch
{
std::initializer_list<bool> _flags;
public:
mswitch(std::initializer_list<bool> const& l) : _flags(l) {}
operator long long() const
{
long long result = 0;
size_t index = 0;
for (bool b : _flags) {
result |= b << index++;
}
return encode(result, _flags.size());
}
};
template<bool head, bool... tail>
struct mcase
{
constexpr mcase() = default;
constexpr operator long long() const
{
return encode(tll(), 1+sizeof...(tail));
}
constexpr long long tll() const { return head | mcase<tail...>().tll() << 1; }
};
template<bool b>
struct mcase<b>
{
constexpr mcase() = default;
constexpr operator long long() const { return encode(tll(), 1); }
constexpr long long tll() const { return b; }
};
}
#define mswitch(head, ...) switch(mswitch::mswitch{head, __VA_ARGS__})
#define mcase(head, ...) case mswitch::mcase<head, __VA_ARGS__>()
#endif // MSWITCH_GUARD_H
编译 g++ -std=c++14 -O2 -Wall -pedantic main.cpp
工作原理
mswitch
和 mcase
对象简单地构建(如果可能,在编译时,使用 constexpr
函数) bool 列表和之间的双射一个开关
能够long long
。由于 mcase
被赋予了编译时常量,因此所有 switch
标签本身实际上都是连续的编译时常量。
关于c++ - 如何在多个条件下分支/切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34414983/