Suppose I have a function which looks like this:
template <class In, class In2>
void func(In first, In last, In2 first2);
I would like this function to call another function which accepts a predicate. My initial instinct was to do something like this:
template <class In, class In2>
void func(In first, In last, In2 first2) {
typedef typename std::iterator_traits<In>::value_type T;
other_func(first, last, first2, std::less<T>());
}
But there is a problem, what if In and In2 are iterators to different types? For example, char* vs int*. Depending on which is In and which is In2 the predicate may be truncating values during its comparison. For example, if In is char* then std::less<char> will be called even if In2 is an int*.
When ::operator< is given two parameters, the compiler is able to deduce the correct type and the standard type promotion rules apply. However, when selecting a predicate to pass to a function, there is no oportunity to have this happen. Is there some clever way to figure out which version of std::less<> I want to pass based on In and In2?
EDIT:
The following example illustrates the problem:
unsigned int x = 0x80000000;
unsigned char y = 1;
std::cout << std::less<unsigned char>()(x, y) << std::endl;
std::cout << std::less<unsigned int>()(x, y) << std::endl;
will output:
1
0
EDIT:
After thinking about it, what I would really like is to be able to do something like this:
typedef typeof(T1() < T2()) T;
other_func(first, last, first2, std::less<T>());
I suppose I could use gcc's __typeof__ extension..., but I don't love that idea either. Any way to get that net effect in a standard conformant way?