我正在使用c ++编写Nintendo DS编码,但这应该适用于所有c ++。
我已经知道了switch语句,但是我需要创建一组if,then和else有多个参数:
void doSomething(int number)
{
...
}
bool left = true;
bool right = false;
bool top = false;
bool bottom = false;
if (left && top && right)
doSomething(1);
else if (top && right && bottom)
doSomething(2);
else if (left && right && bottom)
doSomething(3);
else if (left && top && bottom)
doSomething(4);
感谢任何帮助。
答案 0 :(得分:10)
您可以将四个布尔值转换为二进制数0..15,并使用数组查找参数,如下所示:
int location = (left ? 1<<0 : 0)
| (right ? 1<<1 : 0)
| (top ? 1<<2 : 0)
| (bottom ? 1<<3 : 0);
现在location
的数字从0到15,所以你可以这样做:
int lookup[] = {-1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 3, -1, 4, 2, -1};
int arg = lookup[location];
if (arg != -1) {
doSomething(arg);
}
答案 1 :(得分:1)
如果你真的是心理学家(或混淆者),你可以使用像bitmasks这样的东西:
unsigned char direction = 8; // 1 0 0 0 for l r t b
或与您在问题中使用的惯例保持一致:
unsigned char direction = left + (right << 1) + (top << 2) + (bottom << 3);
然后你会有(*):
switch(direction) {
case 14: // 1 1 1 0
doSomething(1);
break;
case 7: // 0 1 1 1
doSomething(2);
break;
case 13: // 1 1 0 1
doSomething(3);
break;
case 11: // 1 0 1 1
doSomething(4);
break;
}
如果您需要方便地访问单个值:
inline bool left() {return (direction & 8) == 8;}
inline bool right() {return (direction & 4) == 4;}
inline bool top() {return (direction & 2) == 2;}
inline bool bottom() {return (direction & 1) == 1;}
实际上,这应该很快......
(*)作为替代方案,您也可以写:
const unsigned char left_c = 8;
const unsigned char right_c = 4;
const unsigned char top_c = 2;
const unsigned char bottom_c = 1;
测试这样的组合(在开关中接受常量表达式):
switch(direction) {
case (left_c + right_c + top_c):
doSomething(1);
break;
...
}
答案 2 :(得分:0)
将其封装到返回枚举的getSide()中。我假设布尔变量可以从实现或调用doSomething
的类中访问 ...
bool left = true;
bool right = false;
bool top = false;
bool bottom = false;
...
doSomething(getSide());
...
enum Side {
Top, Bottom, Left, Right
}
void doSomething(Side side)
{
...
}
Side getSide () {
if (left && top && right) //Bottom Border
return Side.Bottom;
else if (top && right && bottom) //Left Border
return Side.Left;
else if (left && right && bottom) //Top Border
return Side.Top;
else if (left && top && bottom) //Right Border
return Side.Right;
}
答案 3 :(得分:0)
我添加此响应只是为了说明如何将std::bitset
用于此目的。我知道也许你的目标平台不支持C ++ 11标准,但希望这可以帮助其他人。
#include<iostream>
#include<bitset>
#include<vector>
#include<map>
// The location is represented as a set of four bits; we also need a
// comparator so that we can later store them in a map.
using Location = std::bitset<4>;
struct LocationComparator {
bool operator()(const Location& loc1, const Location& loc2) const {
return loc1.to_ulong() < loc2.to_ulong();
}
};
// the callback (handler) has a signature "void callback()"
using Callback = void (*)( );
// the mapping between location and callback is stored in a simple
// std::map
using CallbackMap = std::map<Location, Callback, LocationComparator>;
// we define the fundamental locations
const Location Top ("1000");
const Location Bottom("0100");
const Location Right ("0010");
const Location Left ("0001");
// ... and define some actions (notice the signature corresponds to
// Callback)
void action_1() { std::cout<<"action 1"<<std::endl;}
void action_2() { std::cout<<"action 2"<<std::endl;}
void action_3() { std::cout<<"action 3"<<std::endl;}
void action_4() { std::cout<<"action 4"<<std::endl;}
// ... now create the map between specific locations and actions
// (notice that bitset can perform logical operations)
CallbackMap callbacks = {
{ Top | Right , action_1 },
{ Top | Left , action_2 },
{ Bottom | Right , action_3 },
{ Bottom | Left , action_4 },
};
// an abstract game element has a location, the interaction will
// depend on the defined callbacks
class GameElement {
public:
GameElement(const Location& location)
: m_location(location) { }
void interact() const {
callbacks[m_location]();
}
virtual ~GameElement() { } // so that others can inherit
private:
Location m_location;
};
int main() {
// create a vector of game elements and make them interact according
// to their positions
std::vector<GameElement> elements;
elements.emplace_back(Top | Right);
elements.emplace_back(Top | Left);
elements.emplace_back(Bottom | Right);
elements.emplace_back(Bottom | Left);
for(auto & e : elements) {
e.interact();
}
}
我使用GCC 4.7.2使用以下命令在OS X上编译它:
g++ locations.cpp -std=c++11
输出结果为:
action 1
action 2
action 3
action 4