Как добавить элементы в std::unordered_map с нестандартным типом ключа?
Пишу:
std::filesystem::path logs_dir;
std::unordered_map<std::filesystem::file_time_type, std::filesystem::path> paths;
for (auto& iter : std::filesystem::directory_iterator(logs_dir))
paths.insert(iter.last_write_time(), iter.path());
Ответ убил:
Error C2664: cannot convert argument 1 from 'std::filesystem::file_time_type' to 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>'
Полный текст ошибки:
Error C2664 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::_Hash<std::_Umap_traits<_Kty,std::filesystem::path,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::insert(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,std::_Node_handle<std::_List_node<std::pair<const std::filesystem::file_time_type,std::filesystem::path>,std::_Default_allocator_traits<_Alloc>::void_pointer>,_Alloc,std::_Node_handle_map_base,_Kty,std::filesystem::path> &&)': cannot convert argument 1 from 'std::filesystem::file_time_type' to 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>'
Исходя из возвращаемых методами типов, всё ок должно было быть. А в тексте ошибки как-то неочевидно, откуда берётся этот _List_iterator. Пытался с std::pair, std::make_pair сделать — не работает.
К слову, если не добавлять элементы в unordered_map, а только объявить его, то будет такая ошибка компиляции:
Error C2280 'std::_Uhash_compare<_Kty,_Hasher,_Keyeq>::_Uhash_compare(const std::_Uhash_compare<_Kty,_Hasher,_Keyeq> &)': attempting to reference a deleted function
Что ещё больше путает. Это какая-то несовместимость стандартных типов STL?
Ответы (2 шт):
Можно хранить в качестве ключа не std::filesystem::file_time_type, а std::chrono::system_clock::rep, он же long long
std::filesystem::path logs_dir;
std::unordered_map<std::chrono::system_clock::rep, std::filesystem::path> paths;
for (auto &iter : std::filesystem::directory_iterator(logs_dir))
paths.insert({ iter.last_write_time().time_since_epoch().count(),iter.path() });
Смысл вроде как тот же, хотя и в ином формате
В метод insert нужно передавать std::pair<const Key, T>
paths.insert(std::make_pair(key, value));
или
paths.insert({key, value});
https://en.cppreference.com/w/cpp/container/unordered_map/insert
У типа std::filesystem::file_time_type нет функции для вычисления хеша, которая необходима для std::unordered_map, но вы можете сами написать её и передать в качестве параметра шаблона
#include <iostream>
#include <filesystem>
#include <unordered_map>
#include <chrono>
#include <functional>
struct FileTimeHash
{
std::size_t operator()(std::filesystem::file_time_type const& time) const {
return std::hash<unsigned long long>{}(std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count());
}
};
int main() {
std::filesystem::path logs_dir(".");
std::unordered_map<std::filesystem::file_time_type, std::filesystem::path, FileTimeHash> paths;
for (auto& iter : std::filesystem::directory_iterator(logs_dir))
paths.insert({iter.last_write_time(), iter.path()});
return 0;
}
https://en.cppreference.com/w/cpp/container/unordered_map
Либо можно использовать std::map
#include <iostream>
#include <filesystem>
#include <map>
int main() {
std::filesystem::path logs_dir(".");
std::map<std::filesystem::file_time_type, std::filesystem::path> paths;
for (auto& iter : std::filesystem::directory_iterator(logs_dir))
paths.insert({iter.last_write_time(), iter.path()});
return 0;
}