How to Return a Vector From a Function in C++
-
How to Return a Vector C++ Using the
vector<T> func()
Notation -
How to Return a Vector C++ Using the
vector<T> &func()
Notation - How to Return a Vector C++ Using Pointers
-
How to Return a Vector C++ Using
std::move
(C++11 and Above) - Conclusion
In C++, functions play a crucial role in modularizing code and improving code reusability. Often, it becomes necessary to return complex data structures, such as vectors, from functions.
A vector is a dynamic array that allows for efficient storage and manipulation of elements. This article will introduce how to return vector from a function efficiently in C++.
How to Return a Vector C++ Using the vector<T> func()
Notation
One of the simplest methods is to return the vector by value. This means that a copy of the vector is created and returned to the caller.
The return by value is the preferred method if we return a vector
variable declared in the function. The efficiency of this method comes from its move semantics.
It means that returning a vector
does not copy the object, thus avoiding wasting extra speed/space. Under the hood, it points the pointer to the returned vector
object, thus providing faster program execution time than copying the whole structure or class would have taken.
Code Input:
#include <iostream>
#include <iterator>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
vector<int> multiplyByFour(vector<int> &arr) {
vector<int> mult;
mult.reserve(arr.size());
for (const auto &i : arr) {
mult.push_back(i * 4);
}
return mult;
}
int main() {
vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> arrby4;
arrby4 = multiplyByFour(arr);
cout << "arr - | ";
copy(arr.begin(), arr.end(), std::ostream_iterator<int>(cout, " | "));
cout << endl;
cout << "arrby4 - | ";
copy(arrby4.begin(), arrby4.end(), std::ostream_iterator<int>(cout, " | "));
cout << endl;
return EXIT_SUCCESS;
}
The above code defines a program that multiplies each element in a given vector by four. It includes a function multiplyByFour
that takes a vector as input and performs the operation. This function returns a new vector with the modified values.
In the main
function, an initial vector arr
is created with values from 1
to 10
. Another vector, arrby4
, is initialized.
The multiplyByFour
function is called with arr
, and the result is stored in arrby4
. Both the original and modified vectors are then printed.
Code Output:
The above code showcases the principles of function usage, vector manipulation, and efficient data handling in C++.
How to Return a Vector C++ Using the vector<T> &func()
Notation
Returning a vector by reference method can be more efficient, as it avoids creating a copy. However, it comes with the responsibility of ensuring the vector’s lifetime exceeds that of the function.
Return by reference notation is best suited for returning large structs and classes. Note that do not return the reference of the local variable declared in the function itself because it leads to a dangling reference.
In the following example, we pass the arr
vector by reference and return it also as a reference.
Code Input:
#include <iostream>
#include <iterator>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
vector<int> &multiplyByFive(vector<int> &arr) { // Return by reference vector
for (auto &i : arr) {
i *= 5;
}
return arr;
}
int main() {
vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> arrby5;
cout << "arr - | ";
copy(arr.begin(), arr.end(), std::ostream_iterator<int>(cout, " | "));
cout << endl;
arrby5 = multiplyByFive(arr);
cout << "arrby5 - | ";
copy(arrby5.begin(), arrby5.end(), std::ostream_iterator<int>(cout, " | "));
cout << endl;
return EXIT_SUCCESS;
}
This code begins by including necessary libraries for input/output operations and working with vectors and iterators.
The multiplyByFive
function is defined, taking a reference to a vector of integers as its argument. This function iterates through the elements of the vector, multiplying each by five.
In the main
function, a vector arr
is initialized with values from 1
to 10
, and another vector, arrby5
, is created to store modified values. The program then prints the original vector arr
.
After calling the multiplyByFive
function with arr
as an argument, the modified vector is assigned to arrby5
, which is then printed. The output demonstrates the transformation of the original vector, where each element in arrby5
is five times the corresponding element in arr
.
Code Output:
This code serves as an illustrative example of function usage and vector manipulation in C++.
How to Return a Vector C++ Using Pointers
Before we dive into using pointers to return vector from a function, it’s crucial to have a solid grasp of both pointers and vectors.
Pointers
A pointer is a variable that holds the memory address of another variable. It allows direct manipulation of memory locations, providing more control over data.
Vectors
A vector is a dynamic array in C++ that can grow or shrink in size as needed. It provides a flexible container for storing elements.
Returning a vector through a pointer allows for dynamic memory allocation, giving more control over memory management.
Code Input:
#include <iostream>
#include <vector>
std::vector<int>* returnVectorByPointer() {
std::vector<int>* vec = new std::vector<int>{1, 2, 3, 4, 5};
return vec;
}
int main() {
std::vector<int>* result = returnVectorByPointer();
for (int num : *result) {
std::cout << num << " ";
}
delete result; // Remember to free the memory
return 0;
}
This code demonstrates a program that dynamically allocates memory for a vector, initializes it with values 1
through 5
, and returns a pointer to the vector. In the main
function, a pointer named result
is assigned the address of the dynamically allocated vector.
The program then uses a loop to iterate through the elements of the vector, printing them to the console.
Code Output:
It’s important to note that when working with dynamically allocated memory, the programmer is responsible for deallocating it to prevent memory leaks.
Hence, the delete result;
statement is used to free the allocated memory before the program terminates. This ensures proper memory management and prevents potential memory issues.
How to Return a Vector C++ Using std::move
(C++11 and Above)
Before we dive into the practical application of std::move
, it’s crucial to grasp the concept of move semantics.
In C++, when an object is moved, it means that its ownership of resources (such as memory) is transferred to another object without the need for expensive deep copying. This can significantly enhance performance when dealing with large or complex data structures.
std::move
is a utility function introduced in C++11 that enables the efficient movement of resources (like a vector) from one object to another. It’s important to note that std::move
doesn’t perform any actual movement itself; rather, it casts its argument into an rvalue
reference, indicating that the object can be moved.
Here is the syntax:
#include <utility> // Include the utility header file
std::move(argument);
Where:
std::move
: A template function defined in the<utility>
header file.argument
: The object that you want to convert into anrvalue
. This can be any valid C++ object.
In this example, std::move
is used to indicate that we’re allowing the contents of vec
to be moved rather than copied. This can lead to more efficient resource management.
Code Input:
#include <iostream>
#include <utility>
#include <vector>
std::vector<int> returnVectorWithMove() {
std::vector<int> vec = {1, 2, 3, 4, 5};
return std::move(vec);
}
int main() {
std::vector<int> result = returnVectorWithMove();
for (int num : result) {
std::cout << num << " ";
}
return 0;
}
This code demonstrates the use of std::move
to efficiently return vector from a function.
In the returnVectorWithMove
function, a vector vec
is created and initialized. By using std::move(vec)
in the return
statement, the resources of vec
are efficiently transferred to the function’s return value.
In main
, the function is called, and the returned vector is assigned to result
. The elements of the result
are then printed.
Code Output:
This code showcases the power of std::move
in optimizing resource management, particularly with dynamic data structures like vectors, enhancing performance by avoiding unnecessary copying.
Conclusion
This article explores various methods for efficiently returning a vector from a function in C++. It starts with the conventional vector<T> func()
notation (return by value), which returns a copy of the vector, highlighting the efficiency gained through move semantics.
The vector<T> &func()
notation, which returns by reference, is discussed next, emphasizing its potential efficiency but requiring careful memory management. Then, using pointers for dynamic memory allocation and precise control over resources is introduced.
Finally, std::move
in C++11 is presented as a powerful tool for efficient resource management and enhanced performance. Each method has distinct advantages, and the choice depends on specific program requirements.
Given the context of C++ and the topics covered in this article, a relevant next step you can explore is the topic of C++ Lambda Function.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook