Is the three-way comparison operator (C++20) supported in Qt 6.9 (clang and libc++) for `QString`, `QDate` and `QTime`?
-
I'm implementing a three-way comparison operator for a class. In such implementation, I use the
<=>
operator with someQString
,QDate
andQTime
objects. According to this post https://www.qt.io/blog/c20-comparisons-in-qt, the operator was added to those classes in Qt 6.7. It's not in the documentation, though.I have 3 setups described in the table below. The program compiles and runs perfectly in setups 2 and 3. However, it fails in setup 1.
Setups
Setup 1 Setup 2 Setup 3 OS freebsd 14 opensuse tumbleweed tuxedo OS (ubuntu-based) Compiler Clang 18 GCC 15 GCC 15 C++ standard C++23 C++23 C++23 Std lib libc++ libstdc++ libstdc++ Qt 6.9 6.9 6.8 Type CI job CI job local machine Result Compilation failure Success Success Error
error: invalid operands to binary expression ('QDate' and 'QDate') 142 | if (const auto cmp = other.lastMessageDateTime.date() <=> lastMessageDateTime.date(); cmp != std::strong_ordering::equal) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: invalid operands to binary expression ('QTime' and 'QTime') 145 | if (const auto cmp = other.lastMessageDateTime.time() <=> lastMessageDateTime.time(); cmp != std::strong_ordering::equal) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: invalid operands to binary expression ('QString' and 'QString') 149 | if (const auto cmp = displayName() <=> other.displayName(); cmp != std::strong_ordering::equal) { | ~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~ error: invalid operands to binary expression ('const QString' and 'const QString') 153 | return accountJid <=> other.accountJid; | ~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~
I tried compiling the project using
clang
on my local machine and it worked, but I had to uselibstdc++
. Apparently, I would need to compile Qt with libc++ to be able to use libc++. So, it's not the same configuration as the CI job.So far the only solution I've found is to write an implementation that avoids using
<=>
with such Qt classes. I don't have a clue what could be going on in this case. -
Does your Makefile explicitely use the clang option for c++20? Might it be defaulting to an older standard? Look at your generated Makefile for CXXOPTS or some such variant.
-
Does your Makefile explicitely use the clang option for c++20? Might it be defaulting to an older standard? Look at your generated Makefile for CXXOPTS or some such variant.
@Kent-Dorfman I don't think so, because in the same implementation I use the
<=>
operator with a member variable that is of typeint
. Additionally, there is no problem with the usage ofstd::strong_ordering
and the project uses other C++20 features. The compiler complaints only about those Qt types using<=>
. -
@Kent-Dorfman I don't think so, because in the same implementation I use the
<=>
operator with a member variable that is of typeint
. Additionally, there is no problem with the usage ofstd::strong_ordering
and the project uses other C++20 features. The compiler complaints only about those Qt types using<=>
.@pehg hi,
While taking a quick look at the header file mentioned in the article I stumbled upon this issue on the llvm project that might explain the situation.
I think you don't have
__cpp_lib_three_way_comparison
defined with clang 18. -
@SGaist Hi,
I remember I saw that LLVM issue but I didn't know how to interpret it and I thought it was fixed. However, I just put the static asserts below in the code and compilation failed in the CI using clang and libc++, while it succeeded in the rest using GCC and libstdc++.#include <compare> // Check if the types support three-way comparison static_assert(std::three_way_comparable<QString>, " ** QString - three-way comparison NOT supported"); static_assert(std::three_way_comparable<QDate>, " ** QDate - three-way comparison NOT supported"); static_assert(std::three_way_comparable<QTime>, " ** QTime - three-way comparison NOT supported"); // Check if the C++20 three-way comparison is available static_assert(__cpp_lib_three_way_comparison >= 201907L, " ** Three-way comparison library NOT available");
I don't know if you refer to
qcompare.h
andqcomparehelpers.h
. I just looked at them and I found usage of__cpp_lib_three_way_comparison
. So, most likely my problem is due to the libc++ issue in the link you mentioned.