I am looking for a way to express interoperability between a class A
and built-in integer types while keeping high flexibility in my code. E.g, I would like to be able to use operator &
freely between (A
and A
), (A
and int
), (int
and A
) and (int
and int
), i.e. I want to have the result of x = y & z
whether x
, y
and z
are type class A
or type int
, just writing:
x = y & z;
The following code works:
#include <cstdlib>
#include <iostream>
class A {
public:
int x;
explicit A(int i) : x(i) {}
operator int() {
return this->x;
}
A operator &(const A& src) const {
return A(this->x & src.x);
}
};
int main() {
int b(2), b2(0), b3(0);
A a(3);
b2 = a & b;
b3 = b & a;
std::cout << b2 << std::endl;
std::cout << b3 << std::endl;
return 0;
}
However, if I add a new cast function from A
to unsigned int
in class A
, this does not work any more because operator &
is defined between (int
and int
) and also (int
and unsigned int
), so when I do:
b2 = a & b
the compiler doesn't know if a
should be cast to int
or unsigned int
, which is logical. I see 2 possibilities to solve it:
- Explicitely implementing
operator &
betweenA
andint
and betweenint
andA
. I don't want that because adding the compatibility with another type would require to re-implement many combinations of all operators which need to be supported. - Forcing implicit conversion from built-in types to
A
, so onlyoperator &
betweenA
andA
is required.
For flexibility and maintainability, solution 2 is much better I think. So I can implement the following class A instead:
class A {
public:
int x;
A(int i) : x(i) {}
A(unsigned int i) : x(i) {}
explicit operator int() {
return this->x;
}
explicit operator unsigned int() {
return static_cast<unsigned int>(this->x);
}
};
A operator &(const A& src1, const A& src2) {
return A(src1.x & src2.x);
}
Now, though conversions from/to int and unsigned int are both defined, I can perform whether (A
and A
), (A
and int
), (int
and A
) and (int
and int
).
However I can't compile the code:
b2 = a & b;
b3 = b & a;
Because as b2
and b3
are int
and (a
& b
) (resp. (b
& a
)) return a A
and cast from A
to int
must now be explicit, I have to write:
b2 = static_cast<int>(a & b);
b3 = static_cast<int>(b & a);
My question (finally) is:
Is there a way to code class A
so I can do:
b2 = a & b;
b3 = b & a;
while keeping only one definition of operator &
, between (A
and A
)? In theory, that could be done overloading operator =(const A&)
of class int
, which is technically impossible.