Passing Parameter Packs by Value or Reference

When should I pass the parameters in a parameter pack by value, reference, const reference, or forwarding reference?

The choice of passing parameters by value, reference, const reference, or forwarding reference depends on your specific use case:

Pass by value when:

  • The parameter is a small, cheap-to-copy type like int, double, bool, etc.
  • You want to work with a copy of the argument and avoid modifying the original

Pass by reference (&) when:

  • The parameter is a large, expensive-to-copy type like a vector or string
  • You need to modify the original argument and have those changes persist after the function call

Pass by const reference (const &) when:

  • The parameter is a large, expensive-to-copy type
  • You don't need to modify the original argument
  • You want to avoid the overhead of copying

Pass by forwarding reference (&&) when:

  • You need to forward the arguments to another function while preserving their value category (lvalue/rvalue)
  • You want to avoid unnecessary copying and enable perfect forwarding

For example:

template <typename... Types>
void LogByValue(Types... Args) {
  // Each arg copied into the function
  (std::cout << ... << Args) << '\n';
}

template <typename... Types>
void LogByReference(Types&... Args) {
  // Each arg passed by reference
  (std::cout << ... << Args) << '\n';
  Args...;  // Potential to modify arguments
}

template <typename... Types>
void LogByConstRef(const Types&... Args) {
  // Each arg passed by const reference
  (std::cout << ... << Args) << '\n';
  // Args...; // Can't modify arguments
}

template <typename... Types>
void LogAndForward(Types&&... Args) {
  (std::cout << ... << Args) << '\n';
  SomeOtherFunction(std::forward<Types>(Args)...);
}

In general, prefer passing by value for small types and const reference for large types. Use non-const references when you need to modify arguments, and forwarding references when you need to forward arguments while preserving their original value category.

Variadic Functions

An introduction to variadic functions, which allow us to pass a variable quantity of arguments

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Recursion vs Fold Expressions
When should I use fold expressions over recursive variadic function calls?
Capturing Lvalues and Rvalues in Variadic Functions
How can I write a variadic function that can accept both lvalue and rvalue arguments?
Zero Argument Variadic Functions
What happens if I call a variadic function with no arguments?
Performance Considerations with Variadic Functions
Are there any performance implications to using variadic functions?
Why use parameter packs instead of just va_args?
I can already write variadic functions in C++ using va_args. Why would I use parameter packs instead?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant