Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Int32 overloads for sf::Time *, /, *= and /= operators  (Read 8490 times)

0 Members and 1 Guest are viewing this topic.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10830
    • View Profile
    • development blog
    • Email
Int32 overloads for sf::Time *, /, *= and /= operators
« on: November 11, 2015, 01:58:53 pm »
Someone on IRC has brought up that multiplying an Int32 with an sf::Time object results in a compiler error, since it's both, implicitly converting to float or Int64, are legal and thus the compiler can't decide and marks it as ambiguous.

So for example this code will produce a compiler error:
sf::Time a = sf::seconds(1.f);
sf::Time b = a * 2;

use of overloaded operator '*' is ambiguous (with operand types 'sf::Time' and 'int')

Since one can't mark operators as explicit, I think we should add overloads for Int32 as well.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #1 on: November 11, 2015, 02:47:18 pm »
But then we have the same problem with all other integer types (char, short, int, and their unsigned variants). We should rather wonder if we could handle math operations with a single overload rather than one for floats and one for ints.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #2 on: November 11, 2015, 03:25:07 pm »
I don't think it's a good idea to provide more overloads, this will only lead to combinatorial explosion. Since the type would be converted internally, people should rather learn to use the correct type in the first place, so they do not unnecessarily lose precision.

The literal postfixes exist for a reason, even if most people don't bother using them ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10830
    • View Profile
    • development blog
    • Email
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #3 on: November 11, 2015, 05:32:59 pm »
One point I forgot to mention is that the returning API provides float (seconds), Int32 (milliseconds) and Int64 (microseconds). So not providing an overload for Int32 can seem a bit unbalanced.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #4 on: November 11, 2015, 06:42:43 pm »
Yes, we need to support this feature. Not being able to multiply a time amount by a number is ridiculous. But adding an overload for sf::Int32 is not enough; one day someone will complain that his unsigned int factor cannot multiply his sf::Time value, and so on with other types.

What about providing a single overload using the 'double' type? I think it's precise enough to handle integer values without any loss.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #5 on: November 11, 2015, 09:14:24 pm »
The true solution would be a template based on std::is_integral and SFINAE or tag-dispatching. But I don't really like that for something so simple (and I'm sure Laurent does so even less ;)), furthermore we would need to re-implement the type trait because we're in C++98.

What about providing a single overload using the 'double' type? I think it's precise enough to handle integer values without any loss.
I see a few problems with double:
  • One could probably construct cases where it leads to rounding errors. Was the reason for providing sf::Int64 in addition to float overloads not to maintain guaranteed integer precision?
  • While it allows implicit conversions from integer types, compilers will omit a warning in those cases -- one that you currently don't have for sf::Int64. Users with "treat warnings as errors" settings can't compile their code anymore.
  • The change breaks code that relied on integer precision at runtime.
However, people who really care about precision could still use the conversion functions from/to microseconds. Still, the fact that we're taking these disadvantages only because people don't bother to use the correct types (and write 4ll instead of 4) doesn't really please me...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

dabbertorres

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
    • website/blog
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #6 on: November 11, 2015, 09:47:43 pm »
The true solution would be a template based on std::is_integral and SFINAE or tag-dispatching. But I don't really like that for something so simple (and I'm sure Laurent does so even less ;))
Why would it be an issue for something so simple? It's a simple problem, so why not use a simple solution? (minus the waiting for C++11/14/17 though)


For now, what about an implicit cast to sf::Int64? Though, an overload for operator= (or overloaded constructor) would be needed as well.

Here's what I thought:
Time& operator=(Int64 i);

operator Int64() const;

Then that would allow arithmetic with whatever sf::Int64 can work with, and since sf::Time uses sf::Int64 internally, it should(?) work out.

That would allow people to do sf::Time a(5) and wanting 5 seconds, but I think that would be their fault for not reading the docs on what time unit the constructor expects. And I don't think that this would cause any compatibility issues (correct me if I'm wrong though!).

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #7 on: November 11, 2015, 09:59:11 pm »
Why would it be an issue for something so simple? It's a simple problem, so why not use a simple solution?
There would still be 2 (in case of SFINAE) or 3 (in case of type dispatching) methods for each operator. The implementation needs to be in the header, we need to trick Doxygen into making the API readable, and we need to specialize a traits template for 13 integral types. Using a template comes with further implications: implicit conversions are no longer considered in overload resolution, thus we again break code.

...not exactly my definition of simple :P


For now, what about an implicit cast to sf::Int64?
That defeats the entire purpose of having a type-safe time class.

(btw: casts are strictly speaking explicit conversions)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

dabbertorres

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
    • website/blog
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #8 on: November 11, 2015, 11:20:26 pm »
Doxygen I can understand. I have some questions about your other points, but it's getting a bit off-topic!

For now, what about an implicit cast to sf::Int64?
That defeats the entire purpose of having a type-safe time class.
(btw: casts are strictly speaking explicit conversions)
[/quote]
Hmm. True, I guess you guys want sf::Time to be more than just a "unit conversion class" of sorts. Makes sense. (And thank you for the wording correction.)

Jebbs

  • Sr. Member
  • ****
  • Posts: 358
  • DSFML Developer
    • View Profile
    • Email
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #9 on: November 12, 2015, 06:53:43 pm »
The true solution would be a template based on std::is_integral and SFINAE or tag-dispatching. But I don't really like that for something so simple (and I'm sure Laurent does so even less ;)), furthermore we would need to re-implement the type trait because we're in C++98.


Why std::is_integral? Wouldn't std::is_arithmetic be better for this? That way you have only a single function for each operator instead of floats plus integer types. It would include double, but people should be aware of the implications and still allowed to use it if they want in my opinion.
DSFML - SFML for the D Programming Language.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Int32 overloads for sf::Time *, /, *= and /= operators
« Reply #10 on: November 12, 2015, 08:53:02 pm »
The idea would be to differentiate between integer and floating point types, not to artificially constrain the type. Non-arithmetic types won't work anyway (and if they do, there's no point in limiting them).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything