-
Please implement some operators for SFML's vector types. For example I want to divide a "Vector2i" by a float. I often run into these problems and have to write small helper functions every time. Implementing these operators isn't much effort and would be much more intentional.
The only misunderstanding for my part I can think of is that we aren't supposed to use SFML's vector types ourselves. You you please specify they are only for the interface to SFML or for general usage?
Do you plan to implement these operators?
-
For example I want to divide a "Vector2i" by a float.
What do you expect to be the result of Vector2i / float, Vector2i or Vector2f?
I don't see the point of providing such operators. While they seem to be convenient, implicit conversions add a lot of error sources. Dividing integer vectors by a float isn't a frequent use case. If you cast, you make more expressive what you want to achieve.
-
Let Vector2i / float = Vector2f like int / float = float in standard C and C++.
You could store the result in an Vector2i again anyway, for something like this Vector2i /= float, since the copy constructor from Vector2i to Vector2f and vice versa already exists in SFML.
-
since the copy constructor from Vector2i to Vector2f and vice versa already exists in SFML.
It is an explicit conversion constructor, so this code does not work:
sf::Vector2f f;
sf::Vector2i i = f;
I think it is a good decision to keep some type safety, it can really prevent a lot of mistakes.
Why do you need implicit conversions? Vector2i is mostly used for pixel coordinates, whereas Vector2f is used for world units. In the rare cases you need the conversion, why not make it explicit?
-
There are many cases where you need to multiply integer vectors with floats.
Let's say there are framebuffers and for each of them there is a float representing their scale. 1.0 would mean window size, 4.0 would mean four times supersampling and 0.5 would mean sampling at half resolution. To set the right render area, we must multiply the integer vector from window.getSize() by the relative framebuffer size which is a float.
-
Let's say there are framebuffers and for each of them there is a float representing their scale. 1.0 would mean window size, 4.0 would mean four times supersampling and 0.5 would mean sampling at half resolution. To set the right render area, we must multiply the integer vector from window.getSize() by the relative framebuffer size which is a float.
sf::Vector2f result = static_cast<sf::Vector2f>(window.getSize())*framebuffer.size();
It's not much effort, doesn't require any special self-written functions and doesn't introduce implicit conversions.
-
In my personal opinion the first line is much less intentional then the second line. With all these explicit casts the code looses expressiveness and clarity.
Vector2i result = static_cast<Vector2i>(static_cast<Vector2f>(windowsize) * factor);
Vector2i result = windowsize * factor;
If you want to store the result in the vector itself, it becomes even worse because you can't use the *= operator.
windowsize = static_cast<Vector2i>(static_cast<Vector2f>(windowsize) * factor);
windowsize *= factor;
But that's just my sense of neat coding. You have reasons for these operators to not exist, and that's understandable.
-
As mentioned, these are conversion constructors. Therefore, you can use the constructor syntax:
Vector2i result(Vector2f(windowsize) * factor);
The problem is: To implement the requested operators, one needs to provide implicit conversions between vectors of different types. This reduces the type safety drastically. Implicit conversions do not express in code that there is a conversion happening, and can easily lead to mistaken types which cause runtime bugs (instead of compiletime messages).
It's always a trade-off between syntax and safety. In general, I prefer to type slightly more when I have less bugs in turn.
-
The problem is: To implement the requested operators, one needs to provide implicit conversions between vectors of different types.
What about returning the given vector type then?
sf::Vector2i operator/ (const sf::Vector2i dividend, float divisor)
{
return sf::Vector2i((int)(dividend.x / divisor), (int)(dividend.y / divisor));
}
-
Vector2i and Vector2f are aliases for Vector2<int> and Vector2<float>, Vector2 is a template.
-
What about returning the given vector type then?
That would be incorrect. And choosing the return type is not really the problem here ;)