strenge schwache Sortierung

Strenge schwache Sortierung: Wenn x <y wahr ist, dann ist! (y <x) wahr. Es versteht sich, dass die beiden Daten in positiver und umgekehrter Reihenfolge an die Vergleichsfunktion übergeben werden und die erhaltenen Ergebnisse konsistent sein müssen .

Wenn Sie den Schlüssel für die Karte anpassen müssen, muss der Schlüssel den Operator< unterstützen und der Operator< ist streng schwach sortiert. Wenn er nicht streng schwach sortiert ist, ist das Ergebnis undefiniert (mögliche Endlosschleife, mögliches Überschreiben von Werten, Windows usw.). Linux verschiedene Es gibt auch Inkonsistenzen zwischen Compiler-Versionen)

Wenn im folgenden Programm die falsche Größenvergleichsmethode verwendet wird, stürzt es während der Zuweisung ab, da die Karte nach der Zuweisung oder dem Einfügen sortiert wird. Beim Vergleich zweier Zahlen ist die Größe nicht unbedingt garantiert, was zu einem Absturz führt.

struct SKey
{
	SKey(int a, int b, int c)
		:m_a(a), m_b(b), m_c(c)
	{
	}
	int m_a;
	int m_b;
	int m_c;
};

//正确的比较大小的方法
struct Skey_Right_Cmp
{
	bool operator()(const SKey& left, const SKey& right) const
	{
		if (left.m_a < right.m_a)
			return true;
		else if (left.m_a > right.m_a)
			return false;
		if (left.m_b < right.m_b)
			return true;
		else if (left.m_b > right.m_b)
			return false;
		return left.m_c < right.m_c;
	}
};

//错误的比较大小的方法
struct Skey_Wrong_Cmp
{
	bool operator()(const SKey& left, const SKey& right) const
	{
		if (left.m_a < right.m_a)
			return true;
		if (left.m_b < right.m_b)
			return true;
		if (left.m_c < right.m_c)
			return true;
		return false;
	}
};

//插入和删除测试,用错误的比较函数在执行map.erase时
//在gcc 4.1上可能导致死循环

template<typename KeyCmp>
void erase_test()
{
	std::map<SKey, int, KeyCmp>data;
	for (int i = 0; i < 10; ++i)
		for (int j = 0; j < 10; ++j)
			for (int k = 0; k < 10; ++k)
				data[SKey(i, j, k)] = 0;
	assert(data.size() == 1000);
	for (int i = 0; i < 1000; ++i)
	{
		std::cout << "erase" << i << "\n";
		data.erase(SKey(std::rand() % 10, std::rand() % 10, std::rand() % 10));
	}
}
	
int main()
{
	std::cout << "begin right test....\n";
	erase_test<Skey_Right_Cmp>();
	std::cout << "begin wrong test....\n";
	erase_test<Skey_Wrong_Cmp>();
	std::cout << "test end" << std::endl;
}

 

Acho que você gosta

Origin blog.csdn.net/SwordArcher/article/details/115796020
Recomendado
Clasificación