Re: [Interest] Some Qt classes (QUuid) do not work with std C++ containers (unordered_map)? [C++ question] [SOLVED]

2021-07-06 Thread Till Oliver Knoll
Am 06.07.21 um 11:30 schrieb Ahmad Samir:
> On 06/07/2021 11:17, Till Oliver Knoll wrote:
>> ...
>> #include  #include  ... // Won't compile
>> std::unordered_map exportPlugins;
>> ...
> Hello. Have a look at
> https://www.kdab.com/qt-datatypes-in-standard-library/
>
> I think that is the issue you're hitting.

From the article: "The Standard Library unordered associative containers
(std::unordered_map, std::unordered_set, and so on), as well as other
third party implementations (like the excellent robin-map
), require, by default, a
specialization of std::hash to be available for the key type we want to use"

That's exactly the answer I was looking for :) So thank you so much,
article is now bookmarked!

Yes, the "joys" of C++ and the lack of explicit interface support (I am
thinking of "Java interfaces" now - to my understanding the C++20
"concepts" feature is meant to implement the "interface" concept to
quite some degree). Many STL features "implicitly expect" some features
of a given class/type. That is particularly true when implementing
"iterators", for instance
(https://www.internalpointers.com/post/writing-custom-iterators-modern-cpp)

"C++ expects some properties from an iterator"

What? Why? Which ones?

|struct Iterator { using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t; using value_type = int; using
pointer = int*; // or also value_type* using reference = int&; // or
also value_type& }; |

Aha: so I just have to *know* about the existence of e.g.
"iterator_category". If I don't set it here my iterator code will still
compile - but I can't use my iterator then for some STL algorithms later
on. And it goes on with adding a begin() and end() method, which are -
implicitly - called when doing a "C++ style iteration". So why are they
to be called begin() and end() and return an iterator of some sort?
Because you need to *know* this.

And the problem with this "you need to know" concept seems to go on with
this std::hash to be implemented by any given class to be used in
unordered_map. To be fair, this is also kind of true for the Java
equivalent HashMap - except that every Java Object already implements a
(default) hashCode() method. But yes, you also need to know about its
existence, in order to possibly re-implement that hashCode() method to
get more meaningful hash values for your custom class - so arguably the
C++ compiler barking at me if no such hash method exists is arguably
better than to silently "use the default hashValue() method"?


Anyway, just some random thoughts of mine about this "need to know" topic :)


This question is hence fully answered for me!


So thanks again for the quick reply,

  Oliver

||


___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Some Qt classes (QUuid) do not work with std C++ containers (unordered_map)? [C++ question]

2021-07-06 Thread Ahmad Samir

On 06/07/2021 11:17, Till Oliver Knoll wrote:

Dear all,

Disclaimer: my C++ knowledge is a bit rusty, especially as far as
standard C++ containers and modern features (C++11, 17, 20) are
concerned. That's exactly the reason why I have started another small
open source project, and also the reason why I now tend to use C++
standard containers (instead of the Qt ones - for no other reason to get
more knowledge about them).

Every then and when I stumble over some Qt classes which do not work
with some given C++ container classes. In some cases I could explain
this for myself based on some "web research", e.g. the "shared data"
concept of e.g. QString does not work with the concept of "unique
pointers" (which are to be stored in some C++ container. And I
intuitively understand that.

But now I stumbled over the following example for which I do not find
any relevant "web research" results (specific to Qt classes). I am
trying to create an unordered hashmap, with QUuid as key, as in:

#include  #include  ... // Won't compile
std::unordered_map exportPlugins;

The compiler (I am currently using the default compiler being used on
macOS 11.4 "Big Sur", with the open source Qt 5.12.2) is complaining
with several error messages (see below for complete error messages), but
they seem to be related to an "implicitly-deleted default constructor"

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/unordered_map:435:
Fehler: call to implicitly-deleted default constructor of
'std::__1::hash'

which seems to be caused by some explicitly deleted default constructor:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/utility:1564:5:
note: '__enum_hash' has been explicitly marked deleted here

Looking at the QUuid class declaration I do not find anything suspicious
at first glance. Specifically I do see a default constructor (but I do
understant that the error message is referring to some other default
constructor of __enum_hash, in the  header). In fact, when I
exchange QUuid with QString, as in:

// This works std::unordered_map exportPlugins;

then everything compiles fine.

This is with a CMake based project, with

set(CMAKE_CXX_STANDARD17)

set(CMAKE_CXX_STANDARD_REQUIREDON)

So this should be using a C++17 compliant compiler.

Questions:

I can use a QString instead of a QUuid here just fine (or use some Qt
container class here instead, namely QMap), but I am curious about
"what's going on here":

* Is this a known limitation of QUuid (and possibly other classes), that
it cannot be used in C++ container classes?

* Or asked differently: why does the "template expansion" (?) get into
the case of __enum_hash (when using QUuid), which apparently has an
explicitly deleted default constructor (or why is the default
constructor of QUuid not sufficient)?

* Is there a way to tell (given the Qt's class declaration) whether a Qt
class is suitable for C++ container classes?

* Or am I doing something wrong here (wrong compiler, wrong project
settings, missing includes, ...)?

As this is most likely a basic C++ noob question I am fine with any RTFM
answers here :) But again, so far I did not find anything related to
QUuid and C++ container classes on the web.

Thank you so much,

Oliver




Hello. Have a look at https://www.kdab.com/qt-datatypes-in-standard-library/

I think that is the issue you're hitting.


[...]
--
Ahmad Samir
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


[Interest] Some Qt classes (QUuid) do not work with std C++ containers (unordered_map)? [C++ question]

2021-07-06 Thread Till Oliver Knoll
Dear all,

Disclaimer: my C++ knowledge is a bit rusty, especially as far as
standard C++ containers and modern features (C++11, 17, 20) are
concerned. That's exactly the reason why I have started another small
open source project, and also the reason why I now tend to use C++
standard containers (instead of the Qt ones - for no other reason to get
more knowledge about them).

Every then and when I stumble over some Qt classes which do not work
with some given C++ container classes. In some cases I could explain
this for myself based on some "web research", e.g. the "shared data"
concept of e.g. QString does not work with the concept of "unique
pointers" (which are to be stored in some C++ container. And I
intuitively understand that.

But now I stumbled over the following example for which I do not find
any relevant "web research" results (specific to Qt classes). I am
trying to create an unordered hashmap, with QUuid as key, as in:

#include  #include  ... // Won't compile
std::unordered_map exportPlugins;

The compiler (I am currently using the default compiler being used on
macOS 11.4 "Big Sur", with the open source Qt 5.12.2) is complaining
with several error messages (see below for complete error messages), but
they seem to be related to an "implicitly-deleted default constructor"

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/unordered_map:435:
Fehler: call to implicitly-deleted default constructor of
'std::__1::hash'

which seems to be caused by some explicitly deleted default constructor:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/utility:1564:5:
note: '__enum_hash' has been explicitly marked deleted here

Looking at the QUuid class declaration I do not find anything suspicious
at first glance. Specifically I do see a default constructor (but I do
understant that the error message is referring to some other default
constructor of __enum_hash, in the  header). In fact, when I
exchange QUuid with QString, as in:

// This works std::unordered_map exportPlugins;

then everything compiles fine.

This is with a CMake based project, with

set(CMAKE_CXX_STANDARD17)

set(CMAKE_CXX_STANDARD_REQUIREDON)

So this should be using a C++17 compliant compiler.

Questions:

I can use a QString instead of a QUuid here just fine (or use some Qt
container class here instead, namely QMap), but I am curious about
"what's going on here":

* Is this a known limitation of QUuid (and possibly other classes), that
it cannot be used in C++ container classes?

* Or asked differently: why does the "template expansion" (?) get into
the case of __enum_hash (when using QUuid), which apparently has an
explicitly deleted default constructor (or why is the default
constructor of QUuid not sufficient)?

* Is there a way to tell (given the Qt's class declaration) whether a Qt
class is suitable for C++ container classes?

* Or am I doing something wrong here (wrong compiler, wrong project
settings, missing includes, ...)?

As this is most likely a basic C++ noob question I am fine with any RTFM
answers here :) But again, so far I did not find anything related to
QUuid and C++ container classes on the web.

Thank you so much,

Oliver


For reference here are the two error messages that I get with QUuid as
key for unordered_map:

#1

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/unordered_map:435:
Fehler: call to implicitly-deleted default constructor of
'std::__1::hash' In file included from
/Users/tknoll/resources/work/Qt/SkyDolly/src/Plugin/src/PluginManager.cpp:26:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/unordered_map:435:11:
error: call to implicitly-deleted default constructor of
'std::__1::hash' : _Hash() {} ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/memory:1956:3:
note: in instantiation of member function
'std::__1::__unordered_map_hasher,
std::__1::hash, true>::__unordered_map_hasher' requested here
__compressed_pair_elem(__default_init_tag) {} ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/unordered_map:906:5:
note: in instantiation of member function
'std::__1::__hash_table, std::__1::__unordered_map_hasher,
std::__1::hash, true>, std::__1::__unordered_map_equal,
std::__1::equal_to, true>,
std::__1::allocator>>::__hash_table' requested here unordered_map() ^
/Users/tknoll/resources/work/Qt/SkyDolly/src/Plugin/src/PluginManager.cpp:37:5:
note: in instantiation of member function
'std::__1::unordered_map,
std::__1::equal_to, std::__1::allocator>>::unordered_map' requested here
PluginManagerPrivate() noexcept ^