Стандартная библиотека GNU C ++ имеет:
struct _Hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(0xc70f6907UL))
{ return _Hash_bytes(__ptr, __clength, __seed); }
/* etc. */
}
как часть его реализации (и это то, что он использует в строках, например). Теперь я хочу использовать этот код тоже … как я могу получить к нему доступ, переносимым способом (то есть таким образом, который будет работать с, скажем, clang libc ++)?
нет. Вы не можете получить доступ к внутренним деталям реализации вашего компилятора переносимым способом. Как это может сработать?
Вы даже не можете быть уверены, что реализация останется там после следующего обновления компилятора тем же поставщиком компилятора. Или, что еще хуже, он все равно может хорошо скомпилироваться, но иметь другое поведение во время выполнения. Это кошмар обслуживания и бесконечная отладочная сессия.
Если вам нужна переносимость или обратная совместимость в будущем, реализуйте свою собственную хеш-функцию и имитируйте поведение _Hash_impl
,
Я думал, может быть, я смогу получить эффект от скучной реализации, фактически не делая этого. Я еще не реализовал это, но я считаю, что это должно работать:
my_allocator
который не позволяет перераспределениеstd::vector<char, my_allocator>
который оборачивает необработанный буфер с std::vector
сортов.void* buf
и размер в байтах n
мы создаем экземпляр вектора-оболочки: std::vector<int, my_allocator<int>> vec(n, {}, buf);
std::hash(vec)
FTW!Причитается @hvd за проинструктировать меня об этом трюке обертывания в прошлом году.