Берем вот такой код:
// hpp
#include <unordered_map>
struct Foo {
int x;
int y;
};
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
// cpp
#include <string>
Foo& Bar::ForY(const std::string& v) {
return xx[v];
}
int main() {}
Внимательно на него смотрим. Потом смотрим еще внимательнее.
Не видим проблемы.
Смотрим еще раз, и опять не видим проблемы.
А потом отправляем его на компиляцию, и получаем ошибку:
/cefs/aa/aad5f6fdba80b622f643f9a5_clang-trunk-20260313/bin/../include/c++/v1/unordered_map:657:74: error: type 'const std::hash<std::string>' does not provide a call operator
657 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Cp& __x) const { return __hash_(__x.first); }
У нас нет инстанса хеша для строки.
😣😣😣😣😣😣
Как это исправляется? Правильно, заголовок строки надо обязательно ставить выше заголовка мапы:
// hpp
#include <string>
#include <unordered_map>
struct Foo {
int x;
int y;
};
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
// cpp
Foo& Bar::ForY(const std::string& v) {
return xx[v];
}
int main() {}
Точнее на самом деле, разумеется, важен не порядок заголовков (хотя там отдельный геморой. И в большинстве codestyle-ах порядок заголовков указывается, хотя на моей памяти "правильный" порядок поменялся ровно на противоположный).
Нужно чтобы string была указана до объявления мапы.
Скомпилируется:
#include <string>
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
Не скомпилируется:
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
#include <string>
Скомпилируется:
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
#include <string>
// Foo& Bar::ForY(const std::string& v) {
// return xx[v];
// }
Скомпилируется:
struct Bar{
std::unordered_map<std::string, Foo> xx;
Foo& ForY(const std::string& v);
};
#include <string>
Foo& Bar::ForY(const std::string& ) {
return xx.begin()->second;
}
И это какая-то лютая хрень, которую не найти не исправить.
Как вообще оно так вышло?