branching based on two boolean variables - c++

Suppose I have two boolean variables, and I want to do completely different things based on their values. What is the cleanest way to achieve this?
Variant 1:
if (a && b)
{
// ...
}
else if (a && !b)
{
// ...
}
else if (!a && b)
{
// ...
}
else
{
// ...
}
Variant 2:
if (a)
{
if (b)
{
// ...
}
else
{
// ...
}
}
else
{
if (b)
{
// ...
}
else
{
// ...
}
}
Variant 3:
switch (a << 1 | b)
{
case 0:
// ...
break;
case 1:
// ...
break;
case 2:
// ...
break;
case 3:
// ...
break;
}
Variant 4:
lut[a][b]();
void (*lut[2][2])() = {false_false, false_true, true_false, true_true};
void false_false()
{
// ...
}
void false_true()
{
// ...
}
void true_false()
{
// ...
}
void true_true()
{
// ...
}
Are variants 3 and 4 too tricky/complicated for the average programmer? Any other variants I have missed?

The first variant is the clearest and most readable, but it can be adjusted:
if (a && b) {
// ...
} else if (a) { // no need to test !b here - b==true would be the first case
// ...
} else if (b) { //no need to test !a here - that would be the first case
// ...
} else { // !a&&!b - the last remaining
// ...
}

You forgot about:
if (a) a_true(b);
else a_false(b);
which is probably the best choice when appliable, and when you truly need 4 different behaviours.
If you have more than 2 bools, I take this as a code smell if I have 2^n different behaviours which don't factorize well like the above. Then I may think about doing:
enum { case1, case2, ... }
int dispatch_cases(bool a, bool b, bool c, ..., bool z);
switch (dispatch_cases(a, b, ..., z))
{
case case1:
...
};
but without context, it is hard to tell whether such complexity is necessary.

IMHO, I will go for variant 3. Because personally, I don't like if/else when I am checking for equality. It clearly states that there are only 4 possibilities.
One minor edit would be:
inline int STATES(int X, int Y) { return (X<<1) | Y; }
// ...
switch (STATES(a,b))
To make it more fancy, you may replace 0,1,2,3 with an enum as well.
enum States {
NONE,
ONLY_B.
ONLY_A,
BOTH
};

For just two booleans, any of them is good and reasonable. One can choose based on his taste.
However, if there are more than two booleans, say four booleans, then I personally would go with lookup table, and I would do this as:
typedef void (*functype)();
//16 functions to handle 16 cases!
void f0() {}
void f1() {}
//...so on
void f15() {}
//setup lookup table
functype lut[] =
{
f0, //0000 - means all bool are false
f1, //0001
f2, //0010
f3, //0011
f4, //0100
f5, //0101
f6, //0110
f7, //0111
f8, //1000
f9, //1001
f10, //1010
f11, //1011
f12, //1100
f13, //1101
f14, //1110
f15 //1111 - means all bool are true
};
lut[MakeInt(b1,b2,b3,b4)](); //call
MakeInt() is easy to write:
int MakeInt(bool b1, bool b2, bool b3, bool b4)
{
return b1 | (b2<<1) | (b3 <<2) | (b4<<3);
}

Related

While loop - how to remove code duplication

It's not the first time I find myself in the following situation:
bool a = some_very_long_computation;
bool b = another_very_long_computation;
while (a && b) {
...
a = some_very_long_computation;
b = another_very_long_computation;
}
I don't want to compute everything in while condition, since computations are long and I want to give them appropriate names.
I don't want to create helper functions, because computation uses many local variables, and passing them all will make the code much less readable (and it will be some_huge_call).
It's unknown whether loop body will be executed at least once.
What is a good pattern in such situation? Currently I face it in C++, but I've encountered this in other languages as well. I can solve it by using additional variable isFirstPass, but it looks ugly (and, I guess, will cause some warnings):
bool a, b;
bool isFirstPass = true;
do {
if (!isFirstPass) {
...
} else {
isFirstPass = false;
}
a = some_very_long_computation;
b = another_very_long_computation;
} while (a && b);
The direct simplification of your code is:
while (
some_very_long_computation &&
another_very_long_computation
) {
...
}
If you want to keep the variables a and b:
bool a, b;
while (
(a = some_very_long_computation) &&
(b = another_very_long_computation)
) {
...
}
If you don't want to put the conditions into the while condition:
while (true) {
bool a = some_very_long_computation;
bool b = another_very_long_computation;
if (!(a && b)) {
break;
}
...
}
You could also create helper lambdas (which have access to local variables):
auto fa = [&]() { return some_very_long_computation; };
auto fb = [&]() { return another_very_long_computation; };
while (fa() && fb()) {
...
}

How to use multiple IR signals for doing the same thing?

I want to use different signals from different IR remotes to control a wheeled robot.
The robot is the Smart robot car kit v1.0 from Elegoo.
I used the infrared_remote_control_car.ino file from the disc with it.
I just added the #define JVC and the operators at the end.
The code looks like this:
#include <IRremote.h>
int receiverpin = 12;
int in1=9;
int in2=8;
int in3=7;
int in4=6;
int ENA=10;
int ENB=5;
int ABS=130;
unsigned long RED;
#define A 16736925
#define B 16754775
#define X 16712445
#define C 16720605
#define D 16761405
#define JVCfront 49816
#define JVCback 49688
#define JVCright 49704
#define JVCleft 49832
#define JVCmenu 49900
#define JVC3ok 49724
#define JVCstop 49856
IRrecv irrecv(receiverpin);
decode_results results;
void _mForward()
{
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go forward!");
}
void _mBack()
{
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go back!");
}
void _mleft()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go left!");
}
void _mright()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go right!");
}
void _mStop()
{
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
Serial.println("STOP!");
}
void setup() {
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
pinMode(receiverpin,INPUT);
Serial.begin(9600);
_mStop();
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results))
{
RED=results.value;
Serial.println(RED);
irrecv.resume();
delay(150);
if(RED==(A || JVCfront))
{
_mForward();
}
else if(RED==(B or JVCback))
{
_mBack();
}
else if(RED==(C or JVCleft))
{
_mleft();
}
else if(RED==(D or JVCright))
{
_mright();
}
else if(RED==(X or JVCstop or JVCmenu or JVC3ok))
{
_mStop();
}
}
}
I tried different ways I saw on the internet for the OR operator as you can see.
Actually, the robot is always going forward.
Does the Serial.println(RED) always print out the expected value?
Your if-elseblock itself does not seem to be problematic at first glance. It doesn't matter if you use || or or. They are equivalent.
The problem is the way you are checking the value:
Therefore that you have parenthesis around your OR statement, you create a bool-value. if(RED==(A || JVCfront) translates to:
is A set or is JVCfront set; meaning, are they != 0 (yes they both are, so this expression is true
is RED == true (no it is not, because true represents 1 in integer)
so the code in that block is not being executed
If you want to solve it with an if-else, you need to:
if(RED == A or RED == JVCfront)
{
_mForward();
}
Anyway, I would suggest a switch-case statement:
switch(RED):
{
case A:
{
//intentional fallthrough
}
case JVCfront:
{
_mForward();
break;
}
case B:
{
//intentional fallthrough
}
case JVCback:
{
_mBack();
break;
}
case C:
{
//intentional fallthrough
}
case JVCleft:
{
_mleft();
break;
}
case D:
{
//intentional fallthrough
}
case JVCright:
{
_mright();
break;
}
case X:
{
//intentional fallthrough
}
case JVCstop:
{
//intentional fallthrough
}
case JVCmenu:
{
//intentional fallthrough
}
case JVC3ok:
{
_mStop();
break;
}
default:
{
_mStop();
}
}
I personally find this kind of code much easier to read, and more understandable.
Please note: If you dont put a break into a case, it automatically executes the next case as well. This is why I wrote //intentional fallthrough in this part of the code. P.e. when case A is executed, nothing happens. It just falls through into case JVCFront and executes everything there.

Have enum value be equivalent to many others

I need to use an enum of various values, in this case various building pieces. Most of these are unique, but there a few that I'd like to be equivalent. I mean as follows:
enum class EPiece: uint8 {
Ceiling,
Table,
Door,
WestWall,
NorthWall,
SouthWall,
EastWall,
Wall,
Floor
};
And I'd like to Wall == WestWall to be true, as well as Wall == NorthWall, etc. However, WestWall == NorthWall is false.
Why I am doing this is because I am making a game where various pieces have a definition based off of what they are/where they are. The player has to place various pieces in a predefined order. The player first has to place a NorthWall piece. They will have available various pieces, and will have to select a Wall piece, and have to attempt to place it on a NorthWall piece. The game checks if the two are equivalent (in this case true), and if the current piece to place is NorthWall. If they attempt to place it on a WestWall piece it should fail since it's not that stage yet.
I thought of doing this through flags, doing something like
WestWall = 0x01,
NorthWall = 0x02,
SouthWall = 0x04,
EastWall = 0x08,
Wall = WestWall | NorthWall | SouthWall | EastWall
and checking by doing something like:
// SelectedPiece is the Piece the Player selected and is attempting to place
// PlacedOnPiece is the Piece that we are attempting to place on top of
// CurrentPieceToPlace is what Piece we are supposed to place at this stage
if ((CurrentPieceToPlace == PlacedOnPiece) && (SelectedPiece & PlacedOnPiece != 0)) {
}
The thing is, I have a lot of pieces and my understanding is to make the flags work I have to use powers of two. That means if I use uint32 I could have a max of 32 Pieces, and I don't want to be limited by that. I might only need around 20, but I don't want to get stuck.
Any suggestions? At this point I need to use an enum, so I can't try a different type.
I'd advise against overloading == to have that meaning. == is usually transitive (if A==B and B==C, then A==C), and if it fails to be transitive otherwise "sane" code will break.
Start with your enum:
enum class EPiece: uint8 {
Ceiling,
Table,
Door,
WestWall,
NorthWall,
SouthWall,
EastWall,
Wall,
Floor
};
Now define an can_be_used_as_a relationship.
bool can_be_used_as_a( EPiece x, EPiece used_as_a_y ) {
if (x==y) return true;
switch(x) {
case Wall: {
switch(used_as_a_y) {
case WestWall:
case EastWall:
case NorthWall:
case EastWall:
return true;
default: break;
}
}
default: break;
}
switch(used_as_a_y) {
case Wall: {
switch(x) {
case WestWall:
case EastWall:
case NorthWall:
case EastWall:
return true;
default: break;
}
}
default: break;
}
return false;
}
now can_be_used_as_a( WestWall, Wall ) is true because a WestWall can be used as a Wall. And similarly, Wall can be used as a WestWall. But a WestWall cannot be used as a EastWall.
If you want slightly cleaner syntax, we can write a named operator:
namespace named_operator {
template<class D>struct make_operator{make_operator(){}};
template<class T, char, class O> struct half_apply { T&& lhs; };
template<class Lhs, class Op>
half_apply<Lhs, '*', Op> operator*( Lhs&& lhs, make_operator<Op> ) {
return {std::forward<Lhs>(lhs)};
}
template<class Lhs, class Op, class Rhs>
auto operator*( half_apply<Lhs, '*', Op>&& lhs, Rhs&& rhs )
-> decltype( invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) ) )
{
return invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
}
}
for the 12 line named operator library, used like:
struct used_as_a_tag{};
static const named_operator::make_operator<used_as_a_tag> can_use_as_a;
bool invoke( EPiece x, used_as_a_tag, EPiece y ) {
return can_be_used_as_a(x,y);
}
and now we can do this:
if (x *can_use_as_a* y) {
}
with the operator occurring between the left and right operands. But this might be going too far.
Finally, consider using enum class instead of enum.
You're going in the right direction. Each wall type you have represents a single bit, and that's awesome. Now all you have to do is to combine them in Wall, and to extract them in your checks, so:
WestWall = 0x01, //0b0001
NorthWall = 0x02, //0b0010
SouthWall = 0x04, //0b0100
EastWall = 0x08, //0b1000
Wall = 0xF //0b1111
Now, to check if one value of the enum represents an other value, you should write something like this:
bool isSame(EPiece first, EPiece second)
{
//if they are the same, they are, well... the same.
if(first == second)
return true;
//this only leaves the bits that are present in both values, so
//if the result is different from 0, then second is a part of first, so
//we return true
else if(first & second)
return true;
//if we are here, then first and second are unrelated
return false;
}
You can define your own comparison operators, like this:
bool operator==(EPiece lhs, EPiece rhs)
{
if (int(lhs) == int(EPiece::Wall) &&
(int(rhs) == int(EPiece::NorthWall) ||
int(rhs) == int(EPiece::SouthWall))) // lots more cases...
{
return true;
}
return int(lhs) == int(rhs);
}
Do note that the declaration (though not necessarily the definition) of the above must be visible wherever you expect to compare these things, so you should declare it right alongside the enum declaration.
Here are two slightly different possibilites:
enum {
Flag0 = 1 << 0,
Flag1 = 1 << 1,
Flag2 = 1 << 2,
Flag3 = 1 << 3,
FlagMask = 0x07
}
if (value & FlagMask) // it's got some flags
{ ... }
if (value & Flag3) // Flag3
{ ... }
and
enum {
ItemA0,
ItemABegin = ItemA0,
ItemA1,
ItemA2,
// insert ItemAs here
ItemAEnd,
ItemB0,
ItemBBegin = ItemB0,
ItemB1,
// insert ItemBs here
ItemBEnd,
}
if (ItemABegin <= value && value < ItemAEnd) // it's some ItemA
{ ... }
if (ItemBBegin <= value && value < ItemBEnd) // it's some ItemB
{ ... }
switch (value) { // switch on specific types
case ItemB0: ... break;
case ItemB1: ... break;
}
the second version still encapsulates the idea of an enumeration type.

Can C++ do something like an ML case expression?

So, I've run into this sort of thing a few times in C++ where I'd really like to write something like
case (a,b,c,d) of
(true, true, _, _ ) => expr
| (false, true, _, false) => expr
| ...
But in C++, I invariably end up with something like this:
bool c11 = color1.count(e.first)>0;
bool c21 = color2.count(e.first)>0;
bool c12 = color1.count(e.second)>0;
bool c22 = color2.count(e.second)>0;
// no vertex in this edge is colored
// requeue
if( !(c11||c21||c12||c22) )
{
edges.push(e);
}
// endpoints already same color
// failure condition
else if( (c11&&c12)||(c21&&c22) )
{
results.push_back("NOT BICOLORABLE.");
return true;
}
// nothing to do: nodes are already
// colored and different from one another
else if( (c11&&c22)||(c21&&c12) )
{
}
// first is c1, second is not set
else if( c11 && !(c12||c22) )
{
color2.insert( e.second );
}
// first is c2, second is not set
else if( c21 && !(c12||c22) )
{
color1.insert( e.second );
}
// first is not set, second is c1
else if( !(c11||c21) && c12 )
{
color2.insert( e.first );
}
// first is not set, second is c2
else if( !(c11||c21) && c22 )
{
color1.insert( e.first );
}
else
{
std::cout << "Something went wrong.\n";
}
I'm wondering if there's any way to clean all of those if's and else's up, as it seems especially error prone. It would be even better if it were possible to get the compiler complain like SML does when a case expression (or statement in C++) isn't exhaustive. I realize this question is a bit vague. Maybe, in sum, how would one represent an exhaustive truth table with an arbitrary number of variables in C++ succinctly? Thanks in advance.
I like Alan's solution but I respectfully disagree with his conclusion that it is too complex. If you have access to C++11 it gives you almost all the tools you need. You only need to write one class and two functions:
namespace always {
struct always_eq_t {
};
template <class lhs_t>
bool operator==(lhs_t const&, always_eq_t)
{
return true;
}
template <class rhs_t>
bool operator==(always_eq_t, rhs_t const&)
{
return true;
}
} // always
Then you can write your function in a way relatively similar to ML:
#include <tuple>
#include <iostream>
void f(bool a, bool b, bool c, bool d)
{
always::always_eq_t _;
auto abcd = std::make_tuple(a, b, c, d);
if (abcd == std::make_tuple(true, true, _, _)) {
std::cout << "true, true, _, _\n";
} else if (abcd == std::make_tuple(false, true, _, false)) {
std::cout << "false, true, _, false\n";
} else {
std::cout << "else\n";
}
}
int
main()
{
f(true, true, true, true);
f(false, true, true, false);
return 0;
}
In C++ you often want to consider is there a sensible type that I can create that will help me write my code more easily? Additionally, I think if you have a background in ML you will benefit a lot from examining C++ templates. They are very helpful in applying a functional programming style in C++.
C++ is traditionally oriented to the individual, and you could never do anything resembling the following regardless of syntax.
if ([a,b,c,d] == [true,true,false, false]) {}
The New C++ standard has some stuff that lets you define arrays of constants inline, and so it is possible to define a class that will take in an array as a constructor and support such comparisons. Something like
auto x = multi_val({a,b,c,d});
if (x == multi_val({true, true, false, false}))
{ ... }
else if (x == multi_val(etc.))
But now to do partial matches like with the _, that's not directly supported and you'd have to make your class even more complex to fudge with that, like using a maybe template type and going
multi_val(true, true, maybe<bool>(), maybe<bool>)
This gets into rather heady C++ territory and definitely not what I would do for something so elementary.
For C++11 assuming that you only want to match a fixed number of booleans and can live without the _ pattern matching then [1] (Expand to the number of variables you require).
I'm still working on an alternate solution using templates to match arbitrary types using lambdas or functors for the expressions.
-Edit-
As promised, [2] pattern matching of arbitrary types incl. unspecified values.
Note a couple of caveats:
This code only works with 4 variables (actually my first foray into template metaprogramming). This could very much be improved with variadic templates.
It works but it's not very tidy or well organised. More a proof of concept that would need to be cleaned up before introducing into production code.
I'm not happy with the match function. I was hoping to use initializer lists to pass the expressions to be evaluated and stop on the first match (with the current implementation every matching condition will be executed) - however i couldn't quickly think of how to pass expression matching objects of different types via the single initializer list.
I can't think of a method for either to validate that the truth table is exhaustive.
Cheers,
-nick
[1]
constexpr int match(bool v, int c)
{
return v ? (1 << c) : 0;
}
constexpr int match(bool a, bool b)
{
return match(a, 0) | match(b, 1);
}
int main()
{
int a = true;
int b = false;
switch(match(a, b))
{
case match(false, false):
break;
case match(false, true):
break;
case match(true, false):
break;
case match(true, true):
break;
}
}
[2]
template<typename V1, typename V2, typename V3, typename V4>
class pattern_match_t
{
private:
V1 value_0;
V2 value_1;
V3 value_2;
V4 value_3;
public:
typedef std::function<void(V1, V2, V3, V4)> expr_fn;
template <typename C1, typename C2, typename C3, typename C4>
pattern_match_t<V1, V2, V3, V4>& match(C1 a, C2 b, C3 c, C4 d, expr_fn fn)
{
if(value_0 == a && value_1 == b && value_2 == c && value_3 == d)
fn(value_0, value_1, value_2, value_3);
return *this;
}
pattern_match_t(V1 a, V2 b, V3 c, V4 d)
: value_0(a), value_1(b), value_2(c), value_3(d)
{
}
};
template<typename T>
class unspecified
{};
template<typename T>
constexpr bool operator==(unspecified<T>, const T&)
{
return true;
}
template<typename T>
constexpr bool operator==(const T&, unspecified<T>)
{
return true;
}
template<typename V1, typename V2, typename V3, typename V4>
pattern_match_t<V1, V2, V3, V4> pattern_match(V1 a, V2 b, V3 c, V4 d)
{
return pattern_match_t<V1, V2, V3, V4>(a, b, c, d);
}
int main()
{
bool test_a = true;
std::string test_b = "some value";
bool test_c = false;
bool test_d = true;
pattern_match(test_a, test_b, test_c, test_d)
.match(true, unspecified<std::string>(), false, true, [](bool, std::string, bool, bool)
{
return;
})
.match(true, "some value", false, true, [](bool, std::string, bool, bool)
{
return;
});
}

Comparing variables in two instances of a class

i have what i hope is a quick question about some code i am building out.. basically i want to compare the variables amongst two instances of a class (goldfish) to see if one is inside the territory of another. they both have territory clases which in turn use a point clase made up of an x and y data-point.
now i was curious to know why the below doesnt work please:
(this bit of code compares two points: a & b, each with two points, a north-east (ne) and south-west (sw) and their x and y plots)
if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
(a->x_sw => b->x_sw && a->y_sw => b-> sw)) {
return true;
} else return false;
I can think of a work around (for instance, by having a get location method), and using a function in the main body to compare, but im curious to know --as a budding c++ programmer -- why the above, or a similar implementation doesnt appear to work.
and also, what would be the CLEANEST and most elegant way to accomplish the above? have a friend function perhaps?
many thanks
edit: added some comments to (hopefully make the variables clearer)
// class point {
// public:
// float x;
// float y;
// point(float x_in, float y_in) { //the 2 arg constructor
// x = x_in;
// y = y_in;
// }
// };
// class territory {
// private:
// point ne, sw;
// public:
// territory(float x_ne, float y_ne, float x_sw, float y_sw)
// : ne(x_ne, y_ne), sw(x_sw,y_sw) {
// }
// bool contain_check(territory a, territory b) {
// //checks if a is contained in b (in THAT order!)
// if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
// (a->x_sw => b->x_sw && a->y_sw => b-> sw)) {
// return true;
// } else return false;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// };
// class goldfish {
// protected:
// float size;
// point pos;
// territory terr;
// public:
// goldfish(float x, float y) : pos(x,y), terr(x-1,y-1,x+1,y+1) { //constructor
// size = 2.3;
// }
// void retreat() { //what happens in the case of loss in attack
// /*
// if(goldfish.size[1] - goldfish.size[2] <= 1 && goldfish.size[1] - goldfish.size[2] > 0) {
// size = size - 0.2;
// }
// */
// }
// void triumph() {
// }
// void attack() {
// }
// // void goldfish()
// };
On first glance: There isn't a => operator. It's called >=
Assuming that your territories are rectangles and your are detecting overlap by comparing the corners of the two classes (ne and nw) you are only checking the northwest and northeast corners which have a region of a line. As #Éric Malenfant mentioned, you have structures as the class members which are accessed by the '.' operator. Those members are ne and sw so to reference them would be: "a.ne.x"
So starting with this:
if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
(a->x_nw => b->x_nw && a->y_nw => b-> nw)) {
return true;
} else return false;
Change it to:
return ( (a.ne.x <= b.ne.x && a.ne.y <= b.ne.y)
&& (a.sw.x >= b.sw.x && a.sw.y >= b.sw.y));
What do you mean by "doesnt work"? I does not compile?
If contain_check is written as shown in your post, a problem is that you are using the arrow operator on non-pointers. Use dot instead:
if ((a.x_ne <= b.x_ne && a.y_ne <= b.ne) //etc.
I noticed two possible problems right off (note: not a C++ expert):
You use => for "greater than or equal to", where it should be >=.
Also, I think b->ne should be b->y_ne.
bool contain_check(territory a, territory b)
You're passing in two territory objects, not pointers to territory objects. Consequently, you'll want to use the . operator to access members instead of the -> operator. Something like:
a.ne
Additionally, you've declared the ne and sw members private, which means that they won't be accessible to unrelated functions. They would need to be public for the contain_check() function to access them.
sorry, i was clearly (very) confused. thanks guys! below works:
if ((a.ne.x <= b.ne.x && a.ne.y <= b.ne.y) &&
(a.sw.x >= b.sw.x && a.sw.y >= b.sw.y)) {
return true;
} else return false;
}
the method bool territory::contain_check(const territory &a, const territory &b); should be declared as static. it makes sense.
or, better, write it as standalone function, because it has nothing to do with the class territory; it checks some kind of relation between two instances, right?