Passing std::vector in C++

Share

Summary

This article explains various methods for passing std::vector to functions in C++, focusing on efficiency and type flexibility using references and templates.

Passing std::vector in C++

Highlights

Passing by Reference and Element Type Specification

When passing a std::vector to a function, it's crucial to pass by (const) reference to avoid expensive copies. The element type of the std::vector must be explicitly specified in the function parameter. For example, a function expecting `const std::vector<int>&` cannot accept `std::vector<double>`.

Limitations of CTAD for Function Parameters

Class Template Argument Deduction (CTAD) works when defining a `std::vector` from initializers (e.g., `std::vector primes{ 2, 3, 5 }`), but it doesn't currently work for deducing function parameter types. Attempting to use `const std::vector& arr` as a function parameter will result in a compile error.

Using Function Templates for Type Flexibility

To handle `std::vector`s of different element types, function templates are used. A template like `template <typename T> void passByRef(const std::vector<T>& arr)` allows the compiler to instantiate specific functions (e.g., `passByRef(const std::vector<int>&)` or `passByRef(const std::vector<double>&)`) based on the type of `std::vector` passed.

Generic Templates and Abbreviated Function Templates

More generic templates, such as `template <typename T> void passByRef(const T& arr)`, can accept any object with an overloaded `operator[]`, including `std::vector`, `std::array`, or `std::string`. C++20 introduces abbreviated function templates using `const auto& arr` for the same purpose. While flexible, this approach can introduce bugs if an object that compiles but doesn't make semantic sense is passed.

Asserting on Array Length and Avoiding Undefined Behavior

Functions that access elements by index should validate the index to prevent undefined behavior from out-of-bounds access. While `assert(arr.size())` can be used for runtime checks in debug builds, a better practice is to avoid functions relying on a minimum vector length. For `constexpr` arrays, `static_assert` can check lengths at compile-time. The best practice is to design functions that don't implicitly rely on minimum array sizes.

Quiz Solution: printElement Function

A solution for a `printElement` function that takes a `std::vector` and an integer index is provided. It checks if the `index` is out of bounds (less than 0 or greater than or equal to `arr.size()`) and prints an error or the element's value accordingly. The `index` parameter is `int` to handle negative inputs, and `static_cast<std::size_t>(index)` is used for array access after validation.

Recently Summarized Articles

Loading...