Why can't one specify which overloaded function to use in transform (a, b, c, d)?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • pablopaul
    New Member
    • Nov 2012
    • 2

    Why can't one specify which overloaded function to use in transform (a, b, c, d)?

    I have been working on an exercise in Accelerated C++ which shows how to use an auxiliary function to call an overloaded function when using transform.

    grade is an overloaded function, so this won't work:

    transform(stude nts.begin(), students.end(), back_inserter(g rades), grade);

    So, as a workaround, we create an auxiliary function double grade_aux(const Student_info& s) that returns the particular overloaded function we want, grade(s). So now we have a transform call that works:

    transform(stude nts.begin(), students.end(), back_inserter(g rade), grade_aux);

    My question is, why couldn't we have saved a step and simply used:

    transform(stude nts.begin(), students.end(), back_insterter( grade), grade(s));

    or something like that to specify which version of our overloaded function we want to call?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    The C++ Standard Library has been designed rather than just coded. That means you need to observe all the library rules. In the case of transform<>, the last argument is either a unary-function or a binary-function. That is, there is an overload of transform<> in the lbrary.

    A unary function is one that has one argument of first-argument-type and returns true or false. A binary function has two arguments and returns true or false. The arguments are first-argument-type and second-argument-type.

    Therefore, any functions you write with these prototypes can be used with transforms<>.

    The function is passed in by address using a function pointer so the compiler needs to know what kind of arguments it has in order to make a correct call. You are allowed only one of these two formats.
    Last edited by weaknessforcats; Nov 29 '12, 11:47 PM.

    Comment

    • pablopaul
      New Member
      • Nov 2012
      • 2

      #3
      I think I understand how transform<> works now, but I don't really understand it from the design perspective. It still seems like one should be able to use:

      transform(stude nts.begin(), students.end(), back_inserter(g rades), grade(s));

      Isn't it clear I'm calling the unary-op version of transform<> because I am using just four parameters? And, by including the parameter (s) with grade, wouldn't this be a more efficient way to tell the compiler which version of grade I wanted to use?

      Perhaps my question would be better stated: Why can't a function pointer point to an overloaded function? Or, why can't an algorithm be designed to recognize an overloaded function?


      Here's the code to which I have been referring:

      Code:
      double median_analysis(const vector<Student_info>& students)
      {
      	vector<double> grades;
      	
      	transform(students.begin(), students.end(), back_inserter(grades), grade_aux);
      
      	return median(grades);
      }
      Code:
      double grade_aux(const Student_info& s)
      {
      	return grade(s);
      }

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        grade_aux is supposed to be a function pointer. In this case it's a pointer to a function that takes a Student_info and returns a double.

        So you just specify grade_aux in your transform<> .

        You probably can't have overloads since you have only one argument and it has to be Student_info.

        transform<> is expecting a pointer to a unary function with an argument of the type pointed at by your iterators.

        Comment

        Working...