爲指針,一般你可以這樣做:
#include <ctime>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <type_traits>
namespace util {
struct sort_pointers {
bool operator() (int *a, int *b) {
return *a < *b;
}
};
template <typename T, bool is_pointer = !std::tr1::is_pointer<T>::value>
struct sort_helper {
typedef std::less<T> wont_compare_pointers;
};
template <typename T>
struct sort_helper<T,false> {
};
template <typename Iterator>
void sort(Iterator start, Iterator end)
{
std::sort(start,
end,
sort_helper
<
typename Iterator::value_type
>::wont_compare_pointers());
}
template <typename Iterator, class Func>
void sort(Iterator start, Iterator end, Func f) {
std::sort(start, end, f);
}
}
int main() {
std::vector<int> v1;
std::vector<int*> v2;
srand(time(0));
for(int i = 0; i < 10; ++i) {
v1.push_back(rand());
}
util::sort(v1.begin(), v1.end());
for(int i = 0; i < 10; ++i) {
v2.push_back(&v1[i]);
}
/* util::sort(v2.begin(), v2.end()); */ //fails.
util::sort(v2.begin(), v2.end(), util::sort_pointers());
return 0;
}
std::tr1::is_pointer
只是這是什麼所謂在Visual Studio 2008,但我認爲加速也有一個,而較新的編譯可能會提供它作爲std::is_pointer
。我相信有人能夠寫出更漂亮的解決方案,但這似乎工作。
但是我必須說,我同意齒輪,這是沒有理由的,程序員應該能夠看到這是否會成爲一個問題,並採取相應的行動。
增加:
你可以概括它多一點,我認爲,自動選擇一個仿函數,將取消引用指針和比較值:
namespace util {
template <typename T>
struct sort_pointers {
bool operator() (T a, T b) {
return *a < *b;
}
};
template <typename T, bool is_pointer = !std::tr1::is_pointer<T>::value>
struct sort_helper {
typedef std::less<T> compare;
};
template <typename T>
struct sort_helper<T,false> {
typedef sort_pointers<T> compare;
};
template <typename Iterator>
void sort(Iterator start, Iterator end)
{
std::sort(start,
end,
sort_helper
<
typename Iterator::value_type
>::compare());
}
}
這樣,你不必想想如果你提供指針來比較與否,它會自動排序。
我們都被這個bug多次咬傷。這就是爲什麼我對這個問題感興趣。不過,我認爲沒有人真的破解過它。我們需要的是確保這種事情不會被編譯,所以當你在另一個完整的程序之後執行它時,它不會留在代碼中。 – 2010-07-09 18:42:54
每次我試圖想出一些有用的東西在這裏說,這一切都歸結爲「讓更聰明的開發人員」。然後我意識到像這樣簡單的事情也發生在聰明的開發人員身上。絕對保留筆記(wiki?)上的代碼中顯示的錯誤「最想要的」,並在代碼審查期間特別注意它們。對初級開發人員來說也是如此。 – corsiKa 2010-07-09 19:28:41