c++ - 无序映射中的用户定义类
问题描述
我在 Windows 上的 VScode 上使用 C++17、MSYS2 MinGW64、OpenGL、stb_image。在下面的代码中,我试图递归搜索每个 .png 文件的特定目录以加载纹理(使用接受 std::string 参数的 Texture 对象)。当我运行我的代码时,我得到了这些错误:
C:/msys64/mingw64/include/c++/10.2.0/tuple: In instantiation of 'std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = Texture]':
C:/msys64/mingw64/include/c++/10.2.0/tuple:1678:63: required from 'std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {}; _T1 = const int; _T2 = Texture]'
C:/msys64/mingw64/include/c++/10.2.0/ext/new_allocator.h:150:4: required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, Texture>; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::__detail::_Hash_node<std::pair<const int, Texture>, false>]'
C:/msys64/mingw64/include/c++/10.2.0/bits/alloc_traits.h:512:17: required from 'static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, Texture>; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::__detail::_Hash_node<std::pair<const int, Texture>, false>; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::__detail::_Hash_node<std::pair<const int, Texture>, false> >]'
C:/msys64/mingw64/include/c++/10.2.0/bits/hashtable_policy.h:2037:36: required from 'std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type* std::__detail::_Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&& ...) [with _Args =
{const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _NodeAlloc = std::allocator<std::__detail::_Hash_node<std::pair<const int, Texture>, false> >; std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type = std::allocator<std::__detail::_Hash_node<std::pair<const int, Texture>, false> >::value_type]'
C:/msys64/mingw64/include/c++/10.2.0/bits/hashtable.h:272:35: required from 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_Scoped_node::_Scoped_node(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__hashtable_alloc*, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Value = std::pair<const int, Texture>; _Alloc = std::allocator<std::pair<const int, Texture> >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__hashtable_alloc = std::_Hashtable<int, std::pair<const int, Texture>, std::allocator<std::pair<const int, Texture> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::__hashtable_alloc]'
C:/msys64/mingw64/include/c++/10.2.0/bits/hashtable_policy.h:739:42: required from 'std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::mapped_type& std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::operator[](std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::key_type&&) [with _Key = int; _Pair = std::pair<const int, Texture>; _Alloc = std::allocator<std::pair<const int, Texture> >; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>; std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::mapped_type = Texture; std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::key_type = int]'
C:/msys64/mingw64/include/c++/10.2.0/bits/unordered_map.h:988:20: required from 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = int; _Tp = Texture; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<std::pair<const int, Texture> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = Texture; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = int]'
src/GameUI.cpp:32:50: required from here
C:/msys64/mingw64/include/c++/10.2.0/tuple:1689:70: error: no matching function for call to 'Texture::Texture()'
1689 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
我该如何解决这个问题?
此外,是否有任何更正或建议可以改进我的代码(尤其是 map.emplace 位)?
代码:
#include "Texture.h"
#include <string>
#include <unordered_map>
#include <filesystem>
#include <iostream>
int main() {
std::unordered_map<int, Texture> map;
std::string path {"resources\\"};
std::string ext {".png"};
size_t count {};
for (auto &p : std::filesystem::recursive_directory_iterator(path)) {
if (p.path().extension() == ext) {
map.emplace(count, Texture{p.path().string()}); // Is this the most efficient way?
std::cout << p.path().string() << std::endl;
}
else if (!p.is_directory())
count++;
}
Texture test = map[7]; // Line 32 in GameUI.cpp
return 0;
}
解决方案
Texture test = map[7];
map[7]
返回纹理上的引用,或者如果尚不存在则默认构造它。如果 Texture 没有默认构造函数,则会出现此错误。
尝试改用map::at()map[7]
,如果不存在则抛出异常。或者map::find()
,如果您不想要例外。或者,好吧,只是定义Texture::Texture()
...
map.emplace(count, Texture{p.path().string()}); // 这是最有效的方法吗?
我想map.emplace(count, p.path().string())
应该够了吧?
推荐阅读
- .net - Azure 函数内存不足
- sql - 了解联合查询
- nginx - 为什么我的 nginx 在我输入 http ip 地址时总是将我重定向到一个 url 域
- android-studio - 错误:运行 firebase deploy 时找不到模块“semver”--仅功能
- python - Jupyter Lab build: RuntimeError: npm dependencies failed to install
- api - 使用 zoom api 进行 oauth 自定义应用程序时出现 Ex 3500 代码错误
- javascript - 获取卡片对象数组并返回卡片的计数(加权值)
- javascript - Javascript中的递归函数显示NaN
- c++ - 即使在使用 skip_permission_denied 时,std::filesystem 递归迭代器也会抛出 permission_denied
- java - 在java中将不可序列化的对象转换为输入流