-4

When we are passing a vector into a function why can't we do it like an array?

For example:

#include<bits/stdc++.h> 
using namespace std;


void func(vector<int> vect)
{
    vect.push_back(30);
}

int main()
{
    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect);

    for (int i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

In this example, it works fine. But if I do it like this why doesn't it work like an array?

#include<bits/stdc++.h> 
using namespace std;

void func(vector<int> *vect)
{
    vect.push_back(30);
}

int main()
{
    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect[0]);

    for (int i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

Just like an array, why is this not possible?

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 2
    The compiler may not care about white space very much, but other humans do. Please take care to format your code to favor readability to make it easier for other users to understand code you share. – François Andrieux Jan 30 '20 at 13:31
  • 3
    You can't add random symbols to your code and expect it to work. Any [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) will explain what a *pointer* is and how does it work. – Yksisarvinen Jan 30 '20 at 13:31
  • 5
    Arrays are weird. Expect nothing else in the language to work like arrays. – Sebastian Redl Jan 30 '20 at 13:32
  • 3
    well-intentioned advice: dont try to learn C++ by guessing how stuff works. A `std::vector` is not a c-array, so it shouldnt be too surprising that it behaves differently – 463035818_is_not_an_ai Jan 30 '20 at 13:35
  • 1
    [Please read this](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – PaulMcKenzie Jan 30 '20 at 13:39
  • @PaulMcKenzie yeah i understood but writting all these header file takes a lot of time – Abhi Sarkar Jan 30 '20 at 13:42
  • 5
    @AbhiSarkar `#include #include ` -- That takes a lot of time? – PaulMcKenzie Jan 30 '20 at 13:45
  • @AbhiSarkar It takes a lot of time, until you spend two days wondering why your function called `sort` or `find` or `make_array` or `get` or almost any other name doesn't want to compile. – Yksisarvinen Jan 30 '20 at 13:46
  • 2
    @Yksisarvinen -- Now that there is a [std::data](https://en.cppreference.com/w/cpp/iterator/data), watch all of the programs with variables and types named `data` start to fall apart with `using namespace std;` being specified. – PaulMcKenzie Jan 30 '20 at 13:49
  • 1
    That header seems to appear more and more, it's becoming a trend, don't know where that comes from. – anastaciu Jan 30 '20 at 13:56
  • @anastaciu i see mostly in programmer use this – Abhi Sarkar Jan 30 '20 at 14:03
  • 1
    @anastaciu Probably competitive programming. – HolyBlackCat Jan 30 '20 at 14:10
  • You shouldn't use it, nor should you use `using namespace std`, you can find more info in [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – anastaciu Jan 30 '20 at 14:11

3 Answers3

2

vect[0] names an int, not a std::vector<int>.

&vect[0] is an int *, not a std::vector<int> *. You can't call a function expecting a std::vector<int> * with a int *

You need to learn references.

void func(vector<int> & vect) // use an existing std::vector<int>
{
    vect.push_back(30);
}
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • 1
    @formerlyknownas_463035818 (assuming vect is non-empty), there is an `int` somewhere that `vect[0]` references. I'm using "names" colloquially – Caleth Jan 30 '20 at 15:03
  • alright, i didnt notice the subtle difference between "names" and "is a", but it completely makes sense – 463035818_is_not_an_ai Jan 30 '20 at 15:33
1

In this function call

func(&vect[0]);

the argument expression has the type int * while the function parameter has the type std::vector<int> *

void func(vector<int> *vect)

and there is no implicit conversion from one type to another.

In essence an object of the type std::vector is already a pointer wrapped in a class. So passing an object of the type std::vector by reference you are in fact simultaneously passing a pointer to the allocated array internally pointed to by the vector.

Pay attention to that in the first program provided in your question you are passing the vector vect by value.

void func(vector<int> vect)
{
    vect.push_back(30);
}

So the function does not change the original object passed to the function. If you want to change the original object then the function parameter should have a referenced type as for example

void func(vector<int> &vect)
{
    vect.push_back(30);
}

Something similar what you mean is done for the standard class std::string in C++ 17. It is the class std::string_view. You can pass a pointer to the first element of an object of the type std::string as you are doing with arrays. But also you need to pass the length of the character array pointed to by the pointer.

Here is a demonstrative program.

#include <iostream>
#include <string>
#include <string_view>

void func( std::string_view s )
{
    std::string reversed_string( s.rbegin(), s .rend() );

    std::cout << reversed_string << '\n';
}

int main()
{
    std::string s( "Hello" );

    func( { &s[0], s.size() } );
}

Its output is

olleH
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

It's quite possible, but you are passing an element of the vector, not the vector itself:

void func(vector<int> *vect) {
    vect->push_back(30);   // <-- pointer type expression
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect); // <-- pass the vector

    for (size_t i = 0; i < vect.size(); i++) // <-- iterator should be size_t type
        cout << vect[i] << " ";

    return 0;
}

If you would like to pass a reference to an element of a vector you can do it too, beware, that element must already exist:

void func(int *vect_elem) {  //<-- pointer to int parameter
    *vect_elem = 30; // <-- assign 30 to the vector element
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect[0]); //<-- reference an existing element of the vector

    for (size_t i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

In this particular case you don't need pointers, a better option is to use references only, like it was already mentioned, since you wouldn't need any dereferencing:

void func(vector<int> &vect) { //<-- parameter reference
    vect.push_back(30); 
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect); // <-- pass the vector

    for (size_t i = 0; i < vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}
void func(int &vect_elem) { //<-- parameter reference
    vect_elem = 30;
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect[0]); //<-- pass the element

    for (size_t i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • @anastaclu i want to know that the &vec and &vec[0] is different from each other or it is same. – Abhi Sarkar Jan 30 '20 at 13:58
  • 1
    @AbhiSarkar `&vec` is a reference to the vector, that means you are passing the address of the vector, that allows you to change all elements of the vector, as well as delete or add elements, `&vec[0]`, here you are passing a reference to an element of the vector, in this case the first element, this means you can only change the value of that element, you cannot change the vector itself. – anastaciu Jan 30 '20 at 14:04