- A counterintuitive breaking change related to new comparisons - 2 Updates
- 1.0 / 0.0 - 1 Update
| wij <wyniijj@gmail.com>: Jan 04 09:59PM -0800 On Tuesday, 4 January 2022 at 19:54:10 UTC+8, wij wrote: > --- > Problem was verified. > It looked to me an overloading issue with std::pair. Let along how C++ interprets the codes' intention, I think adding the conversion function in S should firstly consider that which-ever overloads will fit. Otherwise, the ambiguity issue is difficult to resolve. This indicates a class design problem. |
| Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 05 09:06AM -0800 On 1/4/2022 2:49 PM, Öö Tiib wrote: > make operator int() explicit is also odd ... I think all the > comparison operators of std::pair were removed > by C++20 and replaced with alien flying vessel operator. Potential performance pessimization for aggregate/container comparators is indeed there, which can be seen from the following example #include <utility> #include <iostream> struct S { int a; S(int a) : a(a) {} friend bool operator <(const S& lhs, const S& rhs) { bool b = lhs.a < rhs.a; std::cout << "cmp " << lhs.a << " < " << rhs.a << " = " << b << std::endl; return b; } }; int main() { std::pair<int, S> p1{ 0, 1 }, p2{ 0, 2 }; bool b = p1 < p2; std::cout << "result = " << b << std::endl; b = p2 < p1; std::cout << "result = " << b << std::endl; } This case does not suffer from the original problem (no implicit conversion present), meaning that in this case the comparison results are consistent between C++17 and C++20. However, the paths that lead to those results are still different. When compiled as C++17 it outputs cmp 1 < 2 = 1 result = 1 cmp 2 < 1 = 0 result = 0 When compiled as C++20 it outputs cmp 1 < 2 = 1 result = 1 cmp 2 < 1 = 0 cmp 1 < 2 = 1 result = 0 C++20 still has to route the `std::pair` comparison through the `<=>` operator. And ultimately it has to implement that operator based on the available user-provided `<` comparison for `S`. In general case it takes more calls to `<` to properly calculate the three-state result for `<=>`, as evidenced by the above output. E.g. when "less" comparator returns `false` an extra call is required to tell "equivalent" from "greater". If comparisons for `S` are "heavy", this might easily result in significant pessimization. So, even though the ultimate goal of three-state comparison support in C++20 is to improve the performance of heavy comparisons, it does not come for free: it still requires the user to take active steps to provide efficient `<=>` comparators for their classes. Without it the code might work correctly, but sub-optimally. -- Best regards, Andrey Tarasevich |
| "Öö Tiib" <ootiib@hot.ee>: Jan 04 03:40PM -0800 On Tuesday, 4 January 2022 at 21:49:47 UTC+2, Manfred wrote: > issue with using std::numeric_limits<float>::infinity() embedded in some > application expression, which serves totally different purposes than > inspecting the details of numeric representation of the implementation. Yes, and for such cases when the infinity is used to somehow encode something else I would put it into constant's name (like "beyond_horizon" I mentioned below), as INFINITY or HUGE_VAL would be as confusing. > combination with 'const' and 'constexpr' and all that fuzz - again, good > ol' C wouldn't do that - you'd just use INFINITY or one of the HUGE_VAL > variants, and be done with it. That fuzz I don't understand. It is perfectly OK to write static constexpr, or static const about data member ... maybe I've just done it too lot over the years. :( |
| You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment