For pointers in general you could do this:
#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
was just what it was called in Visual Studio 2008, but I think Boost has one too, and newer compiles might provide it as std::is_pointer
. I'm sure someone would be able to write a prettier solution, but this appears to work.
But I must say, I agree with cogwheel, there is no reason for this, the programmer should be able to see if this is going to be a problem and act accordingly.
Addition:
You can generalize it a bit more I think, to automatically select a functor that will dereference the pointers and compare the values:
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() );
}
}
That way you don't have to think about if you're providing it with pointers to compare or not, it will automatically be sorted out.