Reputation: 2204
I'm working on an algorithm and I need to initialize the vector of ints:
std::vector<int> subs(10)
of fixed length with values:
{-inf, +inf, +inf …. }
This is where I read that it is possible to use MAX_INT
, but it's not quiete correct because the elements of my vector are supposed to be greater than any possible int value.
I liked overrloading comparison operator method from this answer, but how do you initialize the vector with infinitytype
class objects if there are supposed to be an int
?
Or maybe you know any better solution?
Thank you.
Upvotes: 0
Views: 1921
Reputation: 132300
The solution depends on the assumptions your algorithm (or the implementation of your algorithm) has:
sizeof(int)
is 4, use int64_t
), and initialize to (int64_t) 1 + std::numeric_limits<int>:max()
(and similarly for the negative values). But perhaps your algorithm assumes that you can't "exceed infinity" by adding on multiplying by positive numbers?std::variant
like other answers suggest, selecting between an int and infinity; but perhaps your algorithm assumes your elements behave like numbers?float
s or double
s which support -/+ infinity, and restrict them to integrality.So, again, it really just depends and there's no one-size-fits-all solution.
Upvotes: 2
Reputation: 180295
You are already aware of the idea of an "infinite" type, but that implementation could only contain infinite values. There's another related idea:
struct extended_int {
enum {NEGINF, FINITE, POSINF} type;
int finiteValue; // Only meaningful when type==FINITE
bool operator<(extended_int rhs) {
if (this->type==POSINF) return false;
if (rhs.type==NEGINF) return false;
if (this->type==FINITE && rhs.type==POSINF) return false;
if (this->type==NEGINF && rhs.type==FINITE) return false;
assert(this->type==FINITE && rhs.type==FINITE);
return this->finiteValue < rhs.finiteValue)
}
// Implicitly converting ctor
constexpr extended_int(int value) : type(FINITE), finiteValue(value) { }
// And the two infinities
static constexpr extended_int posinf;
static constexpr extended_int neginf;
}
You now have extended_int(5) < extended_int(6)
but also extended_int(5) < extended_int::posinf
Upvotes: 0
Reputation: 11730
You can use a variant (for example, boost::variant) which supports double dispatching, which stores either an int
or an infinitytype
(which should store the sign of the infinity, for example in a bool), then implement the comparison operators through a visitor.
But I think it would be simpler if you simply used a double
instead of int
, and whenever you take out a value that is not infinity, convert it to int. If performance is not that great of an issue, then it will work fine (probably still faster than a variant). If you need great performance, then just use MAX_INT
and be done with it.
Upvotes: 0
Reputation: 15586
AS already said in the comments, you can't have an infinity value stored in int
: all values of this type are well-defined and finite.
If you are ok with a vector of something working as an infinite for ints, then consider using a type like this:
struct infinite
{ };
bool operator < (int, infinite)
{
return true;
}
Upvotes: 1