ReviseAlgo Logo

Functions

Function Parameters

Pass by value, reference, and pointer

Interview: Critical for interviews

Function Parameters

Choosing the right parameter passing strategy is critical for correctness and performance. Each strategy has different semantics for ownership, mutability, and copy overhead.

Strategy Syntax Copies? Modifies Original? Use When
By Valuevoid f(T x)YesNoSmall/cheap types, need local copy
By Referencevoid f(T& x)NoYesMust modify caller's object
By Const Refvoid f(const T& x)NoNoLarge objects, read-only
By Pointervoid f(T x)NoYes (via deref)Optional param (can be nullptr)
By Rvalue Refvoid f(T&& x)NoYes (moves)Move semantics/perfect forwarding

Interview Corner

Q: When should you pass by value versus const reference?

A: Pass by value for cheap-to-copy types (ints, pointers, std::string_view) or when you need a local copy anyway. Pass by const reference for expensive-to-copy types (std::vector, std::string, large structs). The guideline: if sizeof(T) <= 2sizeof(void*), pass by value; otherwise, by const reference.

Q: What is the "sink" parameter pattern?

A: When a function needs to store a parameter (e.g., in a constructor), taking it by value and then moving it is the modern idiom: void setName(std::string name) { m_name = std::move(name); }. This allows the compiler to elide copies when called with temporaries (rvalues) while one copy when called with lvalues.

Common Pitfalls

  • Passing large objects by value in hot loops: Each call copies the entire object, dramatically reducing performance.
  • Returning reference to parameter passed by value: The parameter is a local copy that is destroyed on return.

Best Practices

  • Default to const T& for non-trivial types, and T by value for cheap types (int, char, float, pointers).
  • Use std::optional<T> instead of nullable pointers for optional parameters to express intent clearly.