Function Returning a Vector in C++
In order to code a vector in C++, the vector library has to be included in the program. The vector library has the vector class from which vector objects can be instantiated (created).
The program in which all the code samples of this article are, begins with:
using namespace std ;
A vector of strings is used.
Article Content
Returning Vector by Normal Vector Name
Let the vector of interest be:
The vector is a list of items in a small grocery store. The name, store of this vector, is to be sent as an argument to a function, whose parameter is a vector, but with the name, vtr. The function of interest can be:
vector < string > fn ( vector < string > vtr ) {
Notice the return type of the function definition. The name of the vector is store. This is the argument for the function call. The parameter for the function corresponding to the vector is:
Note that the argument for the function and the parameter name are different (they can still be the same). As soon as the function starts executing, the following statement is made:
This statement is equivalent to the following two statements:
vector < string > vtr = store ;
And so, vtr is a copy of the vector, store. At this point, there are two vectors with the same content in memory for the program. An appropriate C++ main function for the code can be:
vector < string > v = fn ( store ) ;
for ( int i = 0 ; i < v. size ( ) ; i ++ )
Notice that the word store, is the argument of the function call. When the function is called, two copies of the same vector content occur in memory. The function (call) returns a vector, which is received by another vector, v. By the time the program finishes, there are three vectors of the same copy in memory. These three copies of the same content can be reduced to one copy by using a reference vector, or pointer vector. The output for the above program is:
bread, meat, rice, tomato sauce, Cheese,
Returning a Vector Literal
Today (in 2022), a vector literal is the same as an array literal. This literal is called an initializer_list, today in C++. So, returning a vector literal by a function, is the same as returning an initializer_list. Let the initlializer_list be:
Let the function definition to return the initializer_list be,
The initializer_list is composed on the spot in the return statement, and returned. The function definition has no parameter, but has the same return type as its counterpart in the previous section. Let the main C++ function be:
vector < string > v = fn ( ) ;
for ( int i = 0 ; i < v. size ( ) ; i ++ )
The function call, this time, has no argument, but the return value is received by the same vector and type of the previous section.
By the time the program is completing, would there be two copies of the same vector in memory? No. There would be only one copy, which is v. The initializer_list is a kind of expression, called a rvalue. When this kind of expression is no longer needed in memory, can it be erased by C++ in order to have more memory space? It is not important whether it remains in memory after it has been used while the program continues to run. It would be erased if its space is needed. The program output is:
bread, meat, rice, tomato sauce, Cheese,
Returning a Vector Reference
The program here will do what the first program above has done, but only with one copy of the same vector. There will be three different names for the same vector, though. Let the vector of interest be:
The variable , store here , is an ordinary name. Let the function of interest be :
vector < string > & fn ( vector < string > & vtr ) {
Note the presence and position of & in the parameter. It means vtr is a referenced (synonym) vector, and not a copy of the argument to be sent. Note the presence and position of & in the return type. It means that the reference (synonym) of a vector will be returned by the function. Note that the inside statement, “return vtr;” does not have &. Let the C++ main function be:
vector < string > * v = & fn ( store ) ;
for ( int i = 0 ; i < v -> size ( ) ; i ++ )
The signature of the function definition, and the function call statement, are:
respectively. Note again, the presence and position of &, in the return type of the function definition. Note the presence and position of & in the function call statement. The argument of the function call is the ordinary name of the vector, store. The function returns a reference, and it is received by a pointer, v.
And so, there are three different variables in the program, all referring to the same vector memory location (the function returned &vtr, which is a synonym for store). The output is:
Returning a Vector Pointer
The program here will do what the first program above has done, but only with one copy of the same vector. There will be three different names for the same vector. Let the vector of interest be:
The variable , store here , is an ordinary name. Let the function of interest be :
vector < string > * fn ( vector < string > * vtr ) {
Note the presence and position of * in the parameter. It means vtr is a pointer vector, and not a copy of any vector argument to be sent. Note the presence and position of * in the return type. Again, note that the inside statement, “return vtr;” does not have & or *. Let the C++ main function be:
vector < string > * v = fn ( & store ) ;
for ( int i = 0 ; i < v -> size ( ) ; i ++ )
The signature of the function definition, and the function call statement, are:
respectively. Note the presence and position of * in the return type of the function definition. Note the presence and position of & in the function call statement; it is in front of the argument, store, and not in front of fn(), which does not have & or *. The function returns a reference, and it is received by a pointer, v.
And so, there are three different variables in the program, all referring to the same vector memory location. The output is:
Conclusion
A function can return a vector by its normal name. A function can return a vector literal (initializer_list), to be received by a normal vector (name). A vector can return a vector reference, to be received by a vector pointer. A vector can return a vector pointer, still to be received by another vector pointer.
Return a Vector From a Function in C++
This article will introduce how to return a vector from a function efficiently in C++.
Use the vector<T> func() Notation to Return Vector From a Function
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.
Use the vector<T> &func() Notation to Return Vector From a Function
This method uses the return by reference notation, which 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.
Как вернуть vector из функции: по значению или по ссылке?
Есть функция, создающая каким-то определенным образом экземпляр vector . Вопрос: как вернуть этот экземпляр вызывающему?
Правильное с точки зрения логики и стройности программы решение выглядит так:
Тут экземпляр вектора возвращается по значению, что означает потенциальное глубокое копирование локального объекта в контекст вызывающей функции. Сразу возникает сомнение: а что, если вектор огромен — его ж надо будет побайтно перекладывать из одного места в другое? Гораздо “разумнее” было бы написать:
Тут вектор передается по указателю, и стопроцентно ненужного полного копирования не будет. Но такой код выглядит откровенно плохо.
Сравним скорости работы на векторе длиной 100MB. Например, на компиляторе:
Теперь по указателю:
Время в обоих случаях одинаково. Получается, что стоит выбрать первый, “красивый” вариант.
Объяснений тут два. Первый, и возможно самый важный — это RVO, Return value optimization. Это когда компилятор догадывается, что создаваемый локальный экземпляр вектора предназначен для возврата из функции, и сразу создает его в контексте вызывающего кода, чтобы потом не копировать туда. Фактически компилятор реализует передачу по ссылке, но неявно, не портя красоту исходного кода. Данный трюк будет работать для любого класса, не обязательно класса из STL.
Но оптимизация — это негарантированная вещь. Но тут есть еще одно подспорье. Стандартные контейнеры STL реализованы так, что при даже при глубоком копировании фактически копируется только небольшая управляющая структура, а сами данные, размещенные в куче, просто перебрасываются указателем, без их фактического перемещения. Тут, конечно, будет небольшое дополнительное копирование, но оно минимально, и возможно на него стоит пойти ради сохранения красивого кода.
Ну а в контексте C++11, где есть семантика перемещения, вообще не будет лишних копирований, если класс “правильно” реализован (что верно для классов из STL).
Мораль: используйте по возможности контейнеры из STL и оставьте оптимизацию компилятору. Иногда, конечно, компилятор ошибается, но таких случаев гораздо меньше, чем наоборот.
Returning vector from function in C++
It is a preferred method to return vector from function in C++. It can reduce the execution time and space because in this method, an object is not copied for returning a vector. It only points the pointer to the vector which will be returned.
Code:
Further reading:
Vector in C++
Return array from function in C++
Return by Reference
This method is better for returning large classes and structures. We will not return the reference of the local variable which is declared in the function because that can lead to dangling reference. In this method, we pass the vector by reference(& myFunction) and we will return as reference only.
Code:
Conclusion
In this article we discussed two efficient methods to return vector in C++. We can use return by value for smaller classes or structures. Return by reference method is only useful in the case of large structures and classes.
That’s all about how to return vector from function in C++.
Happy Learning!!
Was this post helpful?
Share this
Input Validation in C++
Convert int to Char Array in C++
Related Posts
Author
Related Posts
Pass 2D Array to Function in C++
Table of ContentsWays to Pass a 2D Array to function in C++Pass a 2D Array to a Function by Passing Its PointerPass an Array to the Function by Decaying the Pointer to the ArrayPass a 2D Array to a Function in C++ Without Size by Passing Its ReferenceConclusion Two-dimensional arrays have rows and columns, storing […]
Count Decimal Places in C++
Table of ContentsAccuracy V/S Precision in Counting Decimal Places in C++ ProgramsHow to Count Decimal Places in C++Example 1: Use String Functions to Find Precise Number of Decimal PlacesExample 2: Count Decimal Places Accurately for a NumberExample 3: Create a Program that divides two numbers and returns their decimal placesExample 4: Find the Number of […]
Check if String Is Empty in C++
Table of ContentsWays to Check if String Is Empty in C++Using Empty() methodUsing the Equality OperatorUsing length() methodUsing size() methodConclusion A String is a combination of characters that can store both alphabets and numbers together. In C, there was no concept of string as a datatype so character arrays were used. In C++, this drawback […]
Get Filename from Path in C++
Table of ContentsGet Filename From Path in C++Using find_last_of and substr methodsUsing TemplatesUsing filesysystem library [ C++ 17 ]Conclusion This article explains the various ways to get filename from path using C++ programs. The examples will also describe ways to remove extensions as well if such needs arise. Get Filename From Path in C++ Finding […]
Escape Percent Sign in printf Method in C++
In this post, we will see how to escape percent sign in printf Method in C++. Escape percent sign in Printf Method in C++ printf() method uses percent sign(%) as prefix of format specifier. For example: To use number in prinf() method, we use %d, but what if you actually want to use percent sign […]
Remove Last Element from Vector in C++
Table of ContentsWays to Remove Last Element from Vector in C++Using the vector::pop_back() function to remove last element from vector in C++Using the vector::resize() Function to Remove Last Element from Vector in C++Using the vector::rrase() Function to Remove Last Element from Vector in C++Conclusion Learn about how to remove last element from Vector in C++. […]