У меня есть простая программа, предназначенная для хранения набора объектов C ++ 17 std::filesystem::path
. Поскольку существует std::filesystem::hash_value
, что является частью стандарта, почему этот код не компилируется, если я не предоставлю свой собственный std::hash
?
Когда я компилирую и связываю с использованием gcc 8.1.1 как g++ -std=c++17 -NO_HASH=1 hashtest.cpp -o hashtest -lstdc++fs
, моя хэш-функция включается и все работает отлично. Однако, если я изменю его на -NO_HASH=0
, я получу очень длинный список сообщений об ошибках, ключевым из которых является следующий:
usr/include/c++/8/bits/hashtable.h:195:21: error: static assertion failed: hash function must be invocable with an argument of key type
static_assert(__is_invocable<const _H1&, const _Key&>{},
Вот живая версия Coliru , если вы хотите играть.
Неужели не определено std::hash<std::filesystem::path>
? Что мне не хватает?
Для тех, кому интересно, почему я хочу такую вещь, вот это: https://codereview.stackexchange.com/questions/124307/from-new-q-to-compiler-in-30-seconds
hashtest.cpp
#include <optional>
#include <unordered_set>
#include <filesystem>
#include <string>
#include <iostream>
namespace fs = std::filesystem;
#if NO_HASH
namespace std {
template <>
struct hash<fs::path> {
std::size_t operator()(const fs::path &path) const {
return hash_value(path); }
};
}
#endif
int main()
{
using namespace std::literals;
std::unordered_set< std::optional<fs::path> > paths = {
"/usr/bin"s, std::nullopt, "/usr//bin"s, "/var/log"s
};
for(const auto& p : paths)
std::cout << p.value_or("(no path)") << ' ';
}