首页 > 解决方案 > 无序映射中的用户定义类

问题描述

我在 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;
}

标签: c++unordered-map

解决方案


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())应该够了吧?


推荐阅读