Im having trouble figuring out where to place the overloaded operators i created. should they be in the class they operate on, or inside? both ways are causing me trouble. any pointers would be great.
here is my very basic uint128_t class:
class uint128_t{
private:
uint64_t UPPER, LOWER;
public:
// constructors
uint128_t(){
UPPER = 0;
LOWER = 0;
}
template <typename T>
uint128_t(T val){
UPPER = 0;
LOWER = (uint64_t) val;
}
template <typename S, typename T>
uint128_t(const S & upper_val, const T & lower_val){
UPPER = (uint64_t) upper_val;
LOWER = (uint64_t) lower_val;
}
uint128_t(uint128_t val){
UPPER = val.upper();
LOWER = val.lower();
}
uint64_t upper(){
return UPPER;
}
uint64_t lower(){
return LOWER;
}
};
if the operators are in the class, they work fine. however, i can do uint128_t ^ uint32_t but not uint32_t ^ uint128_t. on the other hand, moving everything outside is giving me error: 'uint128_t operator=(uint128_t, T)' must be a nonstatic member function. also, operator= will not work for a constant input apparently, since the values will be ULLL, which doesnt exist, unless someone know of a way to do so.
what should i do?
Why not a mix of both?
Put operator= inside, and the rest outside.
For the ones that take uint128_t as left-hand-side argument it doesn’t matter, if it’s a right-hand-side argument then it has to be a global function. So for that reason you can put both functions side-by-side if they’re global. You might even get away with a clever macro to have one implementation for both, if only for the commutative ones.