Object-Oriented Programming

Generalizing Functions

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Generalizing Functions

  • The term generalization is overloaded
  • For now, referring to making functions applicable to more situations
  • Very related to concerns

Notice

The following examples are, in many cases, not good design examples

Extremely Limited Sort โ˜น๏ธ

  • Concern
  • The vector to sort
  • Assumption
  • Sort is for a hard-coded vector

Good Sort Interface ๐Ÿ™‚

  • Concern
  • The vector to sort
  • Generalization
  • Replace hard-coded vector with a parameter
  • parameterize the vector

Good Sort Interface Scenario๐Ÿ˜Š

Good Sort Interface Scenario๐Ÿ™

  • Concern
  • The vector to sort
  • Assumption
  • Sort is for the entire vector

Better Sort Interface ๐Ÿ˜Š

  • Concern
  • The vector to sort
    • Generalization
  • Replace complete vector with iterators
  • iterators can refer to the entire vector or a subrange of the vector
  • More flexible parameterization
  • The C++ standard algorithm library takes iterators, not complete containers

Better Sort Interface Scenario ๐Ÿ˜Š

Better Sort Interface Scenarioโ˜น๏ธ

Solution for Descending Sort: Flag Parameterโ˜น๏ธ

Solution for Descending Sort: Separate Functions๐Ÿ™‚

Solution to Descending Sort: Pass Comparison๐Ÿ˜Š

Pass Comparison C++ Template

Extremely Limited Binary Search โ˜น๏ธ

Better Binary Search ๐Ÿ™‚

Generalizing a Function

  • Change from assuming using all of a container, e.g., std::vector<int>& v, to iterators
  • Change a literal value (which is an assumption) into a parameter

Better Sort Interface ๐Ÿ˜Š (Revisited)

Better Sort Interface Scenario

  • Sort only the responses in the even positions
  • Call this a stride of 2
  • The C++ Standard Library does not generally provide stride versions
  • C++23 has the std::ranges::stride_view(). We will cover this more with std::ranges.
  • Many parallel, numerical computing, and scientific computing libraries have the option to use a stride

Sort with Stride ๐Ÿ˜‡

Stride vs. No Stride ๐Ÿ˜Š

Reuse ๐Ÿ˜‡

Questions to Ask

  • Are we assuming a constant/literal that could change?
  • Are we assuming it is applied to the entire data set?

Even More Assumptions

  • Assumption: Container is std::vector
  • Assumption: Container elements are int
  • Assumption: Sorting in ascending order, i.e., smallest to largest
  • Solution: Generalize types using templates
  • Solution: Generalize comparison using templates

Viewpoint of Concerns

  • Why should the search() care about a fixed value? Only cares about the value type int
  • Why should the sort() assume we want to sort the entire container?
  • Why should the sort() assume we want a stride of 1?