Byliśmy pogryzieni przez następujący błąd wiele razy:Jak zmienić relacyjne porównanie wskaźników w błąd?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(int* pn) { cout << *pn << " "; }
int main() {
int* n1 = new int(1);
int* n2 = new int(2);
int* n3 = new int(3);
vector<int*> v;
v.push_back(n1);
v.push_back(n2);
v.push_back(n3);
sort(v.begin(), v.end()); // Here be dragons!
for_each(v.begin(), v.end(), print);
cout << endl;
delete n1; delete n2; delete n3;
}
Problem polega na tym, że std :: sort porównuje wskaźniki liczby całkowitej liczby całkowite, które nie jest tym, co programista przeznaczeniem. Co gorsza, dane wyjściowe mogą być poprawne i deterministyczne (należy rozważyć kolejność adresów zwróconych przez nowe lub przydzielonych na stosie). Głównym problemem jest to, że sortowanie ostatecznie wywołuje operatora < dla T, co rzadko jest dobrym pomysłem, gdy T jest typem wskaźnika.
Czy istnieje sposób, aby temu zapobiec, a przynajmniej uzyskać ostrzeżenie kompilatora? Na przykład, czy istnieje sposób utworzenia niestandardowej wersji std :: sort, która wymaga funkcji porównania, gdy T jest wskaźnikiem?
Wszyscy byliśmy ukąszeni przez tego błędu wiele razy. Właśnie dlatego zainteresowałem się tym pytaniem. Nie sądzę jednak, żeby ktokolwiek naprawdę je złamał. To, czego potrzebujemy, jest czymś, co zapewnia, że tego typu rzeczy się nie kompilują, więc gdy robisz to po innym, nigdy nie można go pozostawić w kodzie. –
Za każdym razem, gdy próbuję wymyślić coś użytecznego tutaj, wszystko sprowadza się do "uzyskania mądrzejszych programistów". Wtedy zdaję sobie sprawę, że proste rzeczy, takie jak to, zdarzają się także inteligentnym programistom. Zdecydowanie przechowuj notatki (wiki?) O "najbardziej poszukiwanych" błędach, które pojawiają się na twoim kodzie, i zwróć na nie szczególną uwagę podczas recenzji kodu. Podwójnie tak w młodszych programistach. – corsiKa