unordered_map insert

0

Mam bardzo głupi i zapewne banalny problem z dodaniem czegoś do unordered_map.
Kompilator piszczy mi niezrozumiałymi błedami, nie mogę znaleźć zadnego przykładu jak to zrobić wiec zwracam się do was.

#include <unordered_map>
    std::unordered_map<std::string, sf::Texture> textures;
    std::string path = "test";
    sf::Texture test;
    textures.insert(path, test); // nie dziala.
}
5
textures.insert(make_pair(path, test));
//albo
textures[path] = test; 
2
#include <iostream>
#include <unordered_map>

struct A
{

};

int main()
{
	std::unordered_map<int, A> m;
	m.insert(std::make_pair(3, A()));
	// lub
	m.emplace(3, A());

	return 0;
}
2
#include <unordered_map>
int main() {
	std::unordered_map<int, int> pff;
	pff.insert({0xDEAD, 0xBEEF});
	return 0;
}
1
gośćabc napisał(a):
#include <iostream>
#include <unordered_map>

struct A
{

};

int main()
{
	std::unordered_map<int, A> m;
	m.insert(std::make_pair(3, A()));
	// lub
	m.emplace(3, A());

	return 0;
}

Nie, nie, nie! Po stokroć nie! Nigdy Nie używaj emplacement w CWUK (containers with unique keys) o ile przewidujesz, że będziesz miał dużo duplikatów. Dla CWUK emplacement powoduje za każdym razem dynamiczną alokację pamięci na nowy node, stworzenie klucza w node (konstruktor) + jeśli node z takim kluczem już istnieje to jeszcze trzeba doliczyć delete zaalokowanej pamięci (destruktor).
Z kolei insert porównuje klucze i jeśli w mapie nie ma takiego klucza to tworzony jest nowy node. W przeciwnym przypadku nic się nie dzieje. Zatem w przypadku duplikacji klucza nie alokacji&dealokacji.
W związku z tym najoptymalniej w przypadku CWUK używać tylko insert i to w takiej formie foo[key] = bar;.

Dla niedowiarków:

  • Scott Meyer, Effective Modern C++ - Item 42: Consider emplacement instead of insertion.
  • Fragment wykładu Scotta Meyers w tym samym temacie:
1

Nie, nie, nie! Po stokroć nie! Nigdy nie używaj emplacement w CWUK (containers with unique keys).

Zapomniałeś tam dodać "o ile przewidujesz, że będziesz miał dużo duplikatów". "Nigdy" to baaaaardzo duże nadużycie.

0
satirev napisał(a):
gośćabc napisał(a):
#include <iostream>
#include <unordered_map>

struct A
{

};

int main()
{
	std::unordered_map<int, A> m;
	m.insert(std::make_pair(3, A()));
	// lub
	m.emplace(3, A());

	return 0;
}

Nie, nie, nie! Po stokroć nie! Nigdy Nie używaj emplacement w CWUK (containers with unique keys) o ile przewidujesz, że będziesz miał dużo duplikatów. Dla CWUK emplacement powoduje za każdym razem dynamiczną alokację pamięci na nowy node, stworzenie klucza w node (konstruktor) + jeśli node z takim kluczem już istnieje to jeszcze trzeba doliczyć delete zaalokowanej pamięci (destruktor).
Z kolei insert porównuje klucze i jeśli w mapie nie ma takiego klucza to tworzony jest nowy node. W przeciwnym przypadku nic się nie dzieje. Zatem w przypadku duplikacji klucza nie alokacji&dealokacji.
W związku z tym najoptymalniej w przypadku CWUK używać tylko insert i to w takiej formie foo[key] = bar;.

Dla niedowiarków:

  • Scott Meyer, Effective Modern C++ - Item 42: Consider emplacement instead of insertion.
  • Fragment wykładu Scotta Meyers w tym samym temacie:

no wiesz, ja zazwyczaj jak chcę mieć duplikaty to wybieram jakiś inny kontener,

naturalnie, o ile przewidujesz, że będziesz chciał nadpisywac keye ("o ile przewidujesz, że będziesz miał dużo duplikatów")

to masz rację, ale bez takich panicznych "nie, nie, nie", bo tutaj raczej takiej potrzeby nie ma

edit:
@Satirev :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1