如何使 unique_ptr 与 Qt 的 QHash 和 QString 一起工作?

How to make unique_ptr work with Qt's QHash and QString?

我正在学习 unique_ptr 的精髓。

我有一个 std::unordered_map 的工作示例,其中包含 std:string 和 std::unique_ptr.

但我无法使用 Qt 的 QString 和 QHash 制作 unique_ptr 示例。他们不会编译提及错误,例如 use of deleted function.

如何使最后两个示例起作用?

编辑 1

如果此信息相关,我正在使用 gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0.

示例 1(有效):unordered_map 和字符串

unordered_map_string.h

#ifndef UNORDERED_MAP_STRING_H
#define UNORDERED_MAP_STRING_H

#include <memory>
#include <string>
#include <unordered_map>

class UnorderedMapString
{
public:
    UnorderedMapString() {};

    std::unordered_map<std::string, std::unique_ptr<std::string>> container;

    void addItem(std::string aKey, std::unique_ptr<std::string> aValue);

    void showItem(std::string aKey);
};

#endif // UNORDERED_MAP_STRING_H

unordered_map_string.cpp

#include "unordered_map_string.h"

#include <iostream>

void UnorderedMapString::addItem(std::string aKey, std::unique_ptr<std::string> aValue)
{
    container[aKey] = std::move(aValue);
}

void UnorderedMapString::showItem(std::string aKey)
{
    std::string *aValue = container[aKey].get();
    std::cout << "Item '" << aKey << "': '" << *aValue << "'\n";
}

main.cpp

#include "unordered_map_string.h"

#include <memory>

int main(int argc, char *argv[])
{
    UnorderedMapString testContainer;

    testContainer.addItem("key 1", std::make_unique<std::string>("one value"));
    testContainer.addItem("key 2", std::make_unique<std::string>("two value"));
    testContainer.addItem("key 3", std::make_unique<std::string>("three value"));

    testContainer.showItem("key 2");
    testContainer.showItem("key 3");
    testContainer.showItem("key 2");

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(unique_ptr_string LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(unique_ptr_string
  main.cpp
  unordered_map_string.h unordered_map_string.cpp
)

示例 2(不工作):unordered_map 和 QString

unordered_map_qstring.h

#ifndef UNORDERED_MAP_QSTRING_H
#define UNORDERED_MAP_QSTRING_H

#include <QString>

#include <memory>
#include <unordered_map>

class UnorderedMapQString
{
public:
    UnorderedMapQString() {};

    std::unordered_map<QString, std::unique_ptr<QString>> container;

    void addItem(QString aKey, std::unique_ptr<QString> aValue);

    void showItem(QString aKey);
};

#endif // UNORDERED_MAP_QSTRING_H

unordered_map_qstring.cpp

#include "unordered_map_qstring.h"

#include <iostream>

void UnorderedMapQString::addItem(QString aKey, std::unique_ptr<QString> aValue)
{
    container[aKey] = std::move(aValue);
}

void UnorderedMapQString::showItem(QString aKey)
{
    QString *aValue = container[aKey].get();
    std::cout << "Item '" << aKey.toStdString() << "': '" << (*aValue).toStdString() << "'\n";
}

main.cpp

#include "unordered_map_qstring.h"

#include <QString>

#include <memory>

int main(int argc, char *argv[])
{
    UnorderedMapQString testContainer;

    testContainer.addItem("key 1", std::make_unique<QString>("one value"));
    testContainer.addItem("key 2", std::make_unique<QString>("two value"));
    testContainer.addItem("key 3", std::make_unique<QString>("three value"));

    testContainer.showItem("key 2");
    testContainer.showItem("key 3");
    testContainer.showItem("key 2");

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(unique_ptr_qstring LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)

add_executable(unique_ptr_qstring
  main.cpp
  unordered_map_qstring.h unordered_map_qstring.cpp
)
target_link_libraries(unique_ptr_qstring Qt${QT_VERSION_MAJOR}::Core)

编辑 2:示例 2 的编译错误

$ make
[ 33%] Building CXX object CMakeFiles/unique_ptr_qstring.dir/main.cpp.o
In file included from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h: In constructor ‘UnorderedMapQString::UnorderedMapQString()’:
/home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:12:27: error: use of deleted function ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() [with _Key = QString; _Tp = std::unique_ptr<QString>; _Hash = std::hash<QString>; _Pred = std::equal_to<QString>; _Alloc = std::allocator<std::pair<const QString, std::unique_ptr<QString> > >]’
   12 |     UnorderedMapQString() {};
      |                           ^
In file included from /usr/include/c++/9/unordered_map:47,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/unordered_map.h:141:7: note: ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() [with _Key = QString; _Tp = std::unique_ptr<QString>; _Hash = std::hash<QString>; _Pred = std::equal_to<QString>; _Alloc = std::allocator<std::pair<const QString, std::unique_ptr<QString> > >]’ is implicitly deleted because the default definition would be ill-formed:
  141 |       unordered_map() = default;
      |       ^~~~~~~~~~~~~
/usr/include/c++/9/bits/unordered_map.h:141:7: error: use of deleted function ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_Hashtable() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _Alloc = std::allocator<std::pair<const QString, std::unique_ptr<QString> > >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<QString>; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, false, true>]’
In file included from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable.h:414:7: note: ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_Hashtable() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _Alloc = std::allocator<std::pair<const QString, std::unique_ptr<QString> > >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<QString>; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, false, true> ’ is implicitly deleted because the default definition would be ill-formed:
  414 |       _Hashtable() = default;
      |       ^~~~~~~~~~
/usr/include/c++/9/bits/hashtable.h:414:7: error: use of deleted function ‘std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>::_Hashtable_base() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<QString>; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<true, false, true>]’
In file included from /usr/include/c++/9/bits/hashtable.h:35,
                 from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable_policy.h:1822:5: note: ‘std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>::_Hashtable_base() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<QString>; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<true, false, true>]’ is implicitly deleted because the default definition would be ill-formed:
 1822 |     _Hashtable_base() = default;
      |     ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1822:5: error: use of deleted function ‘std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, std::__detail::_Default_ranged_hash, true>::_Hash_code_base() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _ExtractKey = std::__detail::_Select1st; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing]’
/usr/include/c++/9/bits/hashtable_policy.h:1373:7: note: ‘std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, std::__detail::_Default_ranged_hash, true>::_Hash_code_base() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _ExtractKey = std::__detail::_Select1st; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing]’ is implicitly deleted because the default definition would be ill-formed:
 1373 |       _Hash_code_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1373:7: error: use of deleted function ‘std::__detail::_Hashtable_ebo_helper<_Nm, _Tp, true>::_Hashtable_ebo_helper() [with int _Nm = 1; _Tp = std::hash<QString>]’
/usr/include/c++/9/bits/hashtable_policy.h:1096:7: note: ‘std::__detail::_Hashtable_ebo_helper<_Nm, _Tp, true>::_Hashtable_ebo_helper() [with int _Nm = 1; _Tp = std::hash<QString>]’ is implicitly deleted because the default definition would be ill-formed:
 1096 |       _Hashtable_ebo_helper() = default;
      |       ^~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1096:7: error: use of deleted function ‘std::hash<QString>::hash()’
In file included from /usr/include/c++/9/string_view:43,
                 from /usr/include/c++/9/bits/basic_string.h:48,
                 from /usr/include/c++/9/string:55,
                 from /usr/include/c++/9/stdexcept:39,
                 from /usr/include/c++/9/array:39,
                 from /usr/include/c++/9/tuple:39,
                 from /usr/include/c++/9/functional:54,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/functional_hash.h:101:12: note: ‘std::hash<QString>::hash()’ is implicitly deleted because the default definition would be ill-formed:
  101 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/9/bits/functional_hash.h:101:12: error: no matching function for call to ‘std::__hash_enum<QString, false>::__hash_enum()’
/usr/include/c++/9/bits/functional_hash.h:82:7: note: candidate: ‘std::__hash_enum<_Tp, <anonymous> >::__hash_enum(std::__hash_enum<_Tp, <anonymous> >&&) [with _Tp = QString; bool <anonymous> = false]’
   82 |       __hash_enum(__hash_enum&&);
      |       ^~~~~~~~~~~
/usr/include/c++/9/bits/functional_hash.h:82:7: note:   candidate expects 1 argument, 0 provided
/usr/include/c++/9/bits/functional_hash.h:101:12: error: ‘std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = QString; bool <anonymous> = false]’ is private within this context
  101 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/9/bits/functional_hash.h:83:7: note: declared private here
   83 |       ~__hash_enum();
      |       ^
In file included from /usr/include/c++/9/bits/hashtable.h:35,
                 from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable_policy.h:1096:7: error: use of deleted function ‘std::hash<QString>::~hash()’
 1096 |       _Hashtable_ebo_helper() = default;
      |       ^~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/string_view:43,
                 from /usr/include/c++/9/bits/basic_string.h:48,
                 from /usr/include/c++/9/string:55,
                 from /usr/include/c++/9/stdexcept:39,
                 from /usr/include/c++/9/array:39,
                 from /usr/include/c++/9/tuple:39,
                 from /usr/include/c++/9/functional:54,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/functional_hash.h:101:12: note: ‘std::hash<QString>::~hash()’ is implicitly deleted because the default definition would be ill-formed:
  101 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/9/bits/functional_hash.h:101:12: error: ‘std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = QString; bool <anonymous> = false]’ is private within this context
/usr/include/c++/9/bits/functional_hash.h:83:7: note: declared private here
   83 |       ~__hash_enum();
      |       ^
In file included from /usr/include/c++/9/bits/hashtable.h:35,
                 from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable_policy.h:1373:7: error: use of deleted function ‘std::__detail::_Hashtable_ebo_helper<1, std::hash<QString>, true>::~_Hashtable_ebo_helper()’
 1373 |       _Hash_code_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1093:12: note: ‘std::__detail::_Hashtable_ebo_helper<1, std::hash<QString>, true>::~_Hashtable_ebo_helper()’ is implicitly deleted because the default definition would be ill-formed:
 1093 |     struct _Hashtable_ebo_helper<_Nm, _Tp, true>
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1093:12: error: use of deleted function ‘std::hash<QString>::~hash()’
/usr/include/c++/9/bits/hashtable_policy.h:1822:5: error: use of deleted function ‘std::__detail::_Hash_code_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::~_Hash_code_base()’
 1822 |     _Hashtable_base() = default;
      |     ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1346:12: note: ‘std::__detail::_Hash_code_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::~_Hash_code_base()’ is implicitly deleted because the default definition would be ill-formed:
 1346 |     struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1347 |       _Default_ranged_hash, true>
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1346:12: error: use of deleted function ‘std::__detail::_Hashtable_ebo_helper<1, std::hash<QString>, true>::~_Hashtable_ebo_helper()’
In file included from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable.h:414:7: error: use of deleted function ‘std::__detail::_Hashtable_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::equal_to<QString>, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true> >::~_Hashtable_base()’
  414 |       _Hashtable() = default;
      |       ^~~~~~~~~~
In file included from /usr/include/c++/9/bits/hashtable.h:35,
                 from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable_policy.h:1770:10: note: ‘std::__detail::_Hashtable_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::equal_to<QString>, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true> >::~_Hashtable_base()’ is implicitly deleted because the default definition would be ill-formed:
 1770 |   struct _Hashtable_base
      |          ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/hashtable_policy.h:1770:10: error: use of deleted function ‘std::__detail::_Hash_code_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::~_Hash_code_base()’
In file included from /usr/include/c++/9/unordered_map:46,
                 from /usr/include/c++/9/functional:61,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:142,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qchar.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:48,
                 from /usr/include/x86_64-linux-gnu/qt5/QtCore/QString:1,
                 from /home/rodrigo/devel/unordered_map-qstring/unordered_map_qstring.h:4,
                 from /home/rodrigo/devel/unordered_map-qstring/main.cpp:1:
/usr/include/c++/9/bits/hashtable.h: In instantiation of ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::~_Hashtable() [with _Key = QString; _Value = std::pair<const QString, std::unique_ptr<QString> >; _Alloc = std::allocator<std::pair<const QString, std::unique_ptr<QString> > >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<QString>; _H1 = std::hash<QString>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, false, true>]’:
/usr/include/c++/9/bits/unordered_map.h:102:11:   required from here
/usr/include/c++/9/bits/hashtable.h:1354:5: error: use of deleted function ‘std::__detail::_Hashtable_base<QString, std::pair<const QString, std::unique_ptr<QString> >, std::__detail::_Select1st, std::equal_to<QString>, std::hash<QString>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true> >::~_Hashtable_base()’
 1354 |     }
      |     ^
make[2]: *** [CMakeFiles/unique_ptr_qstring.dir/build.make:63: CMakeFiles/unique_ptr_qstring.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/unique_ptr_qstring.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

示例 3(不工作):QHash 和 QString

qhash_qstring.h

#ifndef QHASH_QSTRING_H
#define QHASH_QSTRING_H

#include <QHash>
#include <QString>

#include <memory>

class QHashQString
{
public:
    QHashQString() {};

    QHash<QString, std::unique_ptr<QString>> container;

    void addItem(QString aKey, std::unique_ptr<QString> aValue);

    void showItem(QString aKey);
};

#endif // QHASH_QSTRING_H

qhash_qstring.cpp

#include "qhash_qstring.h"

#include <iostream>

void QHashQString::addItem(QString aKey, std::unique_ptr<QString> aValue)
{
    container[aKey] = std::move(aValue);
}

void QHashQString::showItem(QString aKey)
{
    QString *aValue = container[aKey].get();
    std::cout << "Item '" << aKey.toStdString() << "': '" << (*aValue).toStdString() << "'\n";
}

main.cpp

#include "qhash_qstring.h"

#include <memory>

int main(int argc, char *argv[])
{
    QHashQString testContainer;

    testContainer.addItem("key 1", std::make_unique<QString>("one value"));
    testContainer.addItem("key 2", std::make_unique<QString>("two value"));
    testContainer.addItem("key 3", std::make_unique<QString>("three value"));

    testContainer.showItem("key 2");
    testContainer.showItem("key 3");
    testContainer.showItem("key 2");

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(qhash_qstring LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)

add_executable(qhash_qstring
  main.cpp
  qhash_qstring.h qhash_qstring.cpp
)
target_link_libraries(qhash_qstring Qt${QT_VERSION_MAJOR}::Core)

编辑 3:示例 3 的编译错误

$ make
[ 33%] Building CXX object CMakeFiles/qhash_qstring.dir/qhash_qstring.cpp.o
In file included from /usr/include/x86_64-linux-gnu/qt5/QtCore/QHash:1,
                 from /home/rodrigo/devel/qhash-qstring/qhash_qstring.h:4,
                 from /home/rodrigo/devel/qhash-qstring/qhash_qstring.cpp:1:
/usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h: In instantiation of ‘QHashNode<Key, T>::QHashNode(const Key&, const T&, uint, QHashNode<Key, T>*) [with Key = QString; T = std::unique_ptr<QString>; uint = unsigned int]’:
/usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:562:18:   required from ‘QHash<K, V>::Node* QHash<K, V>::createNode(uint, const Key&, const T&, QHash<K, V>::Node**) [with Key = QString; T = std::unique_ptr<QString>; QHash<K, V>::Node = QHashNode<QString, std::unique_ptr<QString> >; uint = unsigned int]’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:762:16:   required from ‘T& QHash<K, V>::operator[](const Key&) [with Key = QString; T = std::unique_ptr<QString>]’
/home/rodrigo/devel/qhash-qstring/qhash_qstring.cpp:7:19:   required from here
/usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:157:52: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = QString; _Dp = std::default_delete<QString>]’
  157 |         : next(n), h(hash), key(key0), value(value0) {}
      |                                                    ^
In file included from /usr/include/c++/9/memory:80,
                 from /home/rodrigo/devel/qhash-qstring/qhash_qstring.h:7,
                 from /home/rodrigo/devel/qhash-qstring/qhash_qstring.cpp:1:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~
make[2]: *** [CMakeFiles/qhash_qstring.dir/build.make:76: CMakeFiles/qhash_qstring.dir/qhash_qstring.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/qhash_qstring.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

示例 2 无法编译,因为 std::unordered_map 要求其键类型为“可散列”:默认情况下,它将使用 std::hash 模板。您可以通过为 QString:

编写专业化来使其工作
#include <functional>     // std::hash
#include <QHashFunctions> // qHash
#include <QString>

template<>
struct std::hash<QString>
{
    std::size_t operator()(QString const& s) const noexcept
    {
        return qHash(s);
    }
};

示例 3 无法编译,因为 Qt 容器使用 implicit sharing 且仅支持复制语义,即使在插入新元素时也是如此。因此编译器正在寻找std::unique_ptr的复制构造函数,它被删除:

unique_ptr(const unique_ptr&) = delete;

此示例无法运行,这是 Qt 和标准库容器之间的根本设计差异。