Why transform doesn't know the argument passed to an overloaded function?

I'm using Koenig/Moo's Accelerated C++, chapter 7, "Using library algorithms", in particular, the transform algorithm.

Using the book's examples, there are several overloaded "grade" functions; e.g., one function takes the structure <Student_info> as the only parameter, another takes three doubles.

Transform takes four parameters: three iterators (range & destination) and, in this case, grade as the function. So, for:

const vector<Student_info> all_students

The range iterators are: all_students.begin & all_students.end. According to the book, because "there are several overloaded versions of the grade
function ... [t]he compiler doesn't know which version to call, because we haven't given grade any arguments."

My question is, why? Isn't the argument to the grade function in transform each of the elements iterated? In other words, each of the elements of all_students.begin to all_students.end is a Student_info -- so won't it choose then the grade function that takes Student_info as a parameter? Isn't that the whole point of insuring that overloaded functions of unique parameters? It doesn't appear to do that -- why not?

Thanks!
The problem is that when the compiler tries to compile the line:

std::transform( s.begin(), s.end(), dest, grade );

It has no idea what transform is going to do with grade. It can't "look ahead" to see how transform() is implemented to see that the argument that will be passed to it is a Student_info.

Doesn't the compiler know that the transform argument for grade is (for instance) s.begin() -- a vector<Student_info> object which must use grade(vector<Student_info>&)?

Is the general rule that if the transform function is pointing to an overloaded function, then you must always create an "auxiliary function" to explicitly state the argument? In this case,

1
2
3
4
double grade_aux(const Student_info& s)
{
       return grade(s);
}


is necessary for std::transform(s.begin(),s.end(),dest,grade_aux)? Even though it is passing the argument range [ s.begin(), s.end() ) which are Student_infos? I guess I'm asking why the compiler doesn't know the type of arguments I'm passing and therefore know which grade function it will use.
No, because you are just passing a function pointer. You aren't telling it which one, std::transform doesn't tell you, it just wants a function pointer. So the compiler can't figure out which one of the overloaded ones to select. And also, it does know the types, they are:

InputIter start
InputIter end
OutputIter someIterator
Some function pointer/class that takes one or two arguments

It doesn't really "know" anything beyond that.
Just off the top of my head, transform's declaration must be something like:

template< typename OutputIter, typename InputIter, typename Compare >
InputIter transform( OutputIter first, OutputIter last, InputIter dest, Compare compare )
{ /* ... */ }

This declaration does not allow the compiler to know the linkage between the iterated type and the parameters to "compare".

Then, are the following conclusions correct:

1. If a function is not overloaded, then you don't have to use an auxiliary function in transform -- transform will use the function, as is, passing it the start and end iterator types (presuming they are the same as the function's arguments).

2. If a function is overloaded, then you must use an auxiliary function.

3. If a function is not overloaded and you use it in a transform, and if you subsequently overload the function, the transform will no longer compile because the compiler will object.
Topic archived. No new replies allowed.