@wasserbord

C++, как скопировать туплы из одного контейнера в другой через итератор?

Итак.
struct my_tuple_hasher
{
  std::size_t operator()(const std::pair<std::string, std::string>& k) const
  {
	  std::string s1, s2, s3;
	  std::tie(s1, s2, s3) = k;
	  return  std::hash<std::string>()(s1) ^ std::hash<std::string>()(s2) ^ std::hash<std::string>()(s3);
  }
};

std::unordered_map<std::tuple<std::string, std::string, std::string>, std::unique_ptr<SOMETHING>, my_tuple_hasher> m;


Тут у нас unordered_map с tuple из 3 строк в качестве ключа и с умным указателем unique_ptr в качестве значения.
Хеш для unordered_map я реализовал, см выше.

Заполняем:
auto ob02 = std::unique_ptr<SOME_TYPE>(new SOME_TYPE());
ob02->... = ...;
m[std::make_tuple("Lorem", "ipsum", "1")] = std::move(ob02);

Без проблем.

А теперь у нас есть еще один unordered_map по имени m2, точно того же типа, но пока пустой.

И нужно все элементы перекинуть в него. (Это НЕ копирование, это потом будет объединение нескольких мапов в 1):
for (auto it = m.begin(); it != m.end(); ++it)
{
    m2[it->first] = std::move(it->second);
}


И вот тут проблема. Ругается! Еще бы, ведь first вместо tuple<string, string, string> возвращает какой-то tr1::tuple<...>

И я вынужден, как идиот, распаковывать it->first через tie, делать из значений новый тупл и класть его в новую мапу - и так каждый тупл.

Например, с std::pair такой проблемы нет.

Что делать? Вложенный std::pair и т.п. не предлагать, только туплы.
  • Вопрос задан
  • 191 просмотр
Пригласить эксперта
Ответы на вопрос 2
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
1) Ваш оператор хэширования просто не скомпилируется. Вы пытаетесь разложить пару на три аргумента.
2) В операторе хэширование не совсем правильное комбинирование хэшей. Посмотрите как boost::hash_combine сделан, например.
3) Проверьте, а точно ли одинаковые типы. А ещё лучше создавайте псевдонимы для всех длинных типов и используйте их.
4) В принципе всё должно работать, и возможно проблема в среде/флагах. Возьмите онлайн компилятор, например godbolt.org и попробуйте откомпилировать там.

PS
Надеюсь, что вы просто экспериментируете, а не пишите реальный проект. Такое использование кортежей -- оверкилл.

PPS
И английское произношение тАпл.
Ответ написан
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
У меня ничего не ругается. VS 2013.

Вероятно, упоминание компилятором "tuple" из пространства имен "tr1" свидетельствует о том, что вам пора обновить инструментарий.

И, вероятно, вместо:
std::size_t operator()(const std::pair<std::string, std::string>& k) const

вы хотели сделать:
std::size_t operator()(const std::tuple<std::string, std::string, std::string>& k) const
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы