如何使 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 和标准库容器之间的根本设计差异。
我正在学习 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 和标准库容器之间的根本设计差异。