TGViewer
C++: Хроники Дурки🚑 C++: Хроники Дурки🚑 @cpp_durka · 916 subscribers
Post #49 2.1K
Сегодня разбираем вот такой рабочий пример. (Рабочий в том смысле, что найден на работе).

Берем вот такой код:


// 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;
}




И это какая-то лютая хрень, которую не найти не исправить.

Как вообще оно так вышло?
godbolt.org Compiler Explorer - C++ (x86-64 clang (trunk)) // hpp 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() {}
  • 🔥 9
  • ❤ 3
More from @cpp_durka
  1. Sep 8, 2026Мошенники заставили пенсионерку из Москвы переписать квартиру на Rust
  2. Aug 31, 2026Всяко разное болезненное есть в С++, из всего болезненного одно из самых болезненных - это…
  3. Aug 24, 2026Если кто не знаком с библиотекой nlohmann/json - она прекрасна. Мои мысли о том, как должн…
  4. Aug 21, 2026#толькосвоимемы Код взят тут. if (dim == 0) idx_dim = i0; else if (dim == 1) idx_dim = i1;…
  5. Aug 17, 2026Ладно, искать баги в компиляторах весело, но недостаточно. Давайте поиграемся в чуть более…
  6. Aug 10, 2026Ладно, разумеется прошлый пост был набросом. Никогда не обновляйте компиляторы без очень с…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →