What should be returned? - c++

I am new to the programming so I don't know how to describe the problems encountered precisely.
Here is the declaration of the function
vector<int>& operator>>(vector<int>& v, int& x){
}
I am just wondering what should be returned for this function.
I am trying to implement the operator >> for the vector class if that is relevant at all to my question.
Thanks for the help

In this case you're probably trying to chain operations: vec >> int1 >> int2;. That means you should return the first parameter so that it can be used in the next call.
vector<int>& operator>>(vector<int>& v, int& x){
x = v.back();
v.pop_back();
return v;
}

vector<int>
Should be returned. If you return vector<int>& then you can't return a new vector, else it will be destroyed going out of scope when the function finishes and the reference will be invalid. If you return the inputted vector v then you will need to mofify it, which is unwise.

Related

Datatype for vector<vector<int> > not matching [duplicate]

This question already has an answer here:
non-const lvalue reference to type ... cannot bind to a temporary of type [duplicate]
(1 answer)
Closed 8 months ago.
So, in the following piece of code i am calculating the exponent of a matrix. Here,
long long mod = (1e+9)+7;
vector<vector<int>> matrixMultiply(vector<vector<int>>& A, vector<vector<int>>& B){
vector<vector<int>> ans(2, vector<int> (2));
for(int i = 0; i < 2; ++i)
for(int j = 0; j < 2; ++j)
for(int k = 0; k < 2; ++k){
ans[i][j] += ((A[i][k]%mod) * (A[k][j]%mod))%mod;
ans[i][j] = ans[i][j]%mod;
}
return ans;
}
vector<vector<int>> matrixPower(int n, vector<vector<int>>& M){
if(n==1) {
return M;
}
vector<vector<int>> temp = matrixPower(n/2,M);
if(n%2==0){
return matrixMultiply(temp,temp);
}
else{
return matrixMultiply(matrixMultiply(temp,temp),M);
}
}
int solve(int A){
vector< vector<int>> M{{1,1},{1,0}};
vector< vector<int>> Mpower = matrixPower(A-1,M);
return Mpower[0][0];
}
int main(){
cout << solve(4);
return 0;
}
Here when i run the code, I get the following error,
main.cpp: In function 'std::vector<std::vector<int> > matrixPower(int,
std::vector<std::vector<int> >&)': main.cpp:41:49: error: invalid initialization of non-const
reference of type 'std::vector<std::vector<int> >&' from an rvalue of type
'std::vector<std::vector<int> >' return matrixMultiply(matrixMultiply(temp,temp),M);
~~~~~~~~~~~~~~^~~~~~~~~~~
main.cpp:21:25: note: initializing argument 1 of 'std::vector<std::vector<int> >
matrixMultiply(std::vector<std::vector<int> >&, std::vector<std::vector<int> >&)'
vector<vector<int>> matrixMultiply(vector<vector<int>>& A, vector<vector<int>>& B){
^~~~~~~~~~~~~~
However when I do little bit of modification in my matrixPower function, like this,
vector<vector<int>> matrixPower(int n, vector<vector<int>>& M){
if(n==1) {
return M;
}
vector<vector<int>> temp = matrixPower(n/2,M);
vector<vector<int>> multiplied_matrix = matrixMultiply(temp,temp);
if(n%2==0){
return multiplied_matrix;
}
else{
return matrixMultiply(multiplied_matrix,M);
}
}
It works without any compilation error.
Please help me understood what exactly is the difference between this two pieces of code.
Thank you.
The parameters of matrixMultiply are of type vector<vector<int>>& - i.e. "reference to vector of vector of int". (The & means reference.)
This means that instead of the compiler making a copy of the matrix, and giving that copy to matrixMultiply to use, it instead just gives it a reference (basically just the memory address) to the existing copy that the caller already has.
However, in your first example, the caller doesn't actually store the matrix returned by the first matrixMultiply call anywhere, it just passes it straight to the second matrixMultiply call. This is known as a temporary object, and can't be passed as a non-const reference.
If you want the efficiency of passing by reference, without having to create the multiplied_matrix variable, you could change matrixMultiply to take const references instead - i.e. vector<vector<int>> const&. This means that matrixMultiply can't modify the original matrices, but it can still use the data in them to create a new (multiplied) matrix. In this case you would not need to make any changes to the body of matrixMultiply to allow it to work with const references.
So why can you pass a temporary object to a const reference? Well, if the callee were allowed to modify the referenced object, where would those modifications go? There's no actual variable in the caller's scope where that object "lives", so clearly the caller doesn't expect to receive information back from the callee through the reference.
Ok, but what if the caller wants to modify the parameter for its own purposes (e.g. because it wants to make some changes to the parameter, and doesn't want to have to copy it)? Well, that's where "move semantics" come in. This gets a bit more complicated though, so you may just want to use a const reference for now, and then if your function needs to take a copy of the referenced object, it can do that explicitly.
Here are some links for more info on temporary objects and move semantics:
https://learn.microsoft.com/en-us/cpp/cpp/temporary-objects?view=msvc-170
Temporary objects - when are they created, how do you recognise them in code?
What is move semantics?

return a string having maximum possible value by using elements of the array for ex for a[]={3,5,34,30,9} you will return "9534330" not working

bool comp(int a,int b)
{
return to_string(a)+to_string(b)>to_string(b)+to_string(a);
}
string Solution::largestNumber(const vector<int> &a)
{
sort(a.begin(),a.end(), comp);
string ans="";
for(auto i=a.begin();i<a.end();i++)
{
ans+=to_string(*i);
}
return ans[0]=='0'? "0" : ans;
}
You program works, after removing the const of const vector<int> &a. A constant vector cannot be modified and std::sort tries to modify it.
If you cannot modify the signature of the function, you can directly copy and create a new vector<int>.
A better solution consists in creating a std::vector<std::string>, with the help of the to_string function, and then to sort it. This avoids the need to repetidly use this to_string function in the comp function, and is more efficient.

what's the difference between "vector<int>& a " and "vector<int> a"?

I'm the beginner in C++. I try to write a program to rotate a vector one by one
i.e., {1,2,3,4,5} --> {2,3,4,5,1} --> {3,4,5,1,2}
vector<vector<int>> allrot(const vector<int>& a)
{
vector<vector<int>> result;
for (int i = 0; i < a.size(); i ++ ){
rotate(a.begin(), a.begin() + 1, a.end());
result.push_back(a);
}
return result;
}
This doesn't work, and I have several questions.
Why should I use vector<int>& a rather than vector<int> a ?
What's wrong with my code ?
Thank you for your help
When you pass vector<int> then function gets a copy of that vector. You can do anything you want with it in the function and your original data would not change.
When you pass vector<int>& then function gets the reference which means that any changes in the function would modify the original data.

Use of * and & together in function signature

I was playing through c++ and trying to understand vector and its signature .
In below method printPrimes I need to use pointer with address of why ?
Is vector<int> &primes not enough as from main method printPrimes is already sending address .
void printPrimes(long long l, long long r, vector<int>* &primes) {
// some code
}
vector<int>* sieve() {
vector<int> *prime = new vector<int>();
return prime;
}
int main() {
vector<int> *primes = sieve();
printPrimes(l, r, primes);
return 0;
}
I need to use pointer with address of
Here, & does not mean "address of"; it means the type "reference to".
It's clearer if you write it not like this:
vector<int>* &primes
but like this:
vector<int>*& primes
Though the choice of whitespace is artificial, that better documents that this & is "part of the type".
Have some types:
std::vector<T> = A vector of Ts
std::vector<T>& = A reference to a vector of Ts
std::vector<T>* = A pointer to a vector of Ts
std::vector<T>*& = A reference to a pointer to a vector of Ts
std::vector<T>*** = A pointer to a pointer to a pointer to a vector of Ts
std::vector<T>**& = A reference to a pointer to a pointer to a vector of Ts
…and so forth.
As for why you need a vector<int>*& for printPrimes to do its job, we could not tell you without actually being able to see it. I will say that it seems unlikely it needs a pointer at all, and that if it wants to modify that pointer it's going to cause problems with the new and delete in the calling scope.
In fact, all that dynamic allocation is completely pointless and only complicates things.
The following was likely intended instead:
void printPrimes(long long l, long long r, vector<int>& primes) {
// some code
}
vector<int> sieve() {
vector<int> prime;
return prime;
}
int main() {
vector<int> primes = sieve();
printPrimes(l, r, primes);
}
vector<int>* &primes parameter has to be read this way:
Reference to a pointer of vector of int
and not
Address of a pointer of vector of int (which, you are right, would be useless)
Passing by reference allows to directly manipulate any instance outside of scope (like with pointers, but a safer way since a reference cannot be nullptr, and its existence is auto-managed (no need to delete)).
In c++ & in function parameter used to pass parameter by reference. vector<int>* &primes declares primes to be a reference to a pointer to vector<int>.
If printPrimes means to print only the vector passed to the function then the signature
void printPrimes(long long l, long long r, vector<int> &primes);
can also do the job.
Reference to a pointer is needed when the pointer passed to the function is need to be modified and it's effect is expected to seen in the caller function.
void foo(int*& p){
p = new int[10];
// rest of the code
}
if a function bar is calling foo like
void bar(/* some parameters */){
// ...
int *p;
foo(p);
// rest of the code
}
foo is modifying the pointer itself and this modification will be seen to bar also and memory allocated to p can be accessed from bar.

Using Vectors with functions, Pointer Issues

I have gotten myself completely muddled up and confused when it comes to these points and vectors.
I have two functions
vector<int>& add(vector<int>& num1, vector<int>& num2){
vector<int> ansVec;
....
return ansVec;
}
and
vector<int>& multiply(vector<int>& num1, vector<int>& num2){
...
return add( multiply(num1, num2), multiply(num1, num2));
}
The issue seems to be that I'm returning a reference to a local variable.
How could I pass the entire vector, and not just the reference?
you cannot always return by reference,
here are some solutions to your problem :
1) put the result in a container parameter:
void add(vector<int>& num1, vector<int>& num2 ,vector<int>* result)
and fill the result vector with the result of the computation
2) return by value :
vector<int> add(vector<int>& num1, vector<int>& num2);
note that here you actually copy each element from the temporary vector you will use for the computation, to the returned vector
3) return a pointer (or a some kind of smart pointer) to a vector allocated on heap
vector<int>* add(vector<int>& num1, vector<int>& num2)
{
vector<int>* res = new vector<int>();
...
return res ;
}
note that here the clients of this code must not forget to delete the vector
or , for example with boost::shared_ptr , or std::shared_ptr if you have c++11:
shared_ptr<vector<int>> add(vector<int>& num1, vector<int>& num2)
{
shared_ptr<vector<int>> res (new vector<int>());
...
return res ;
}
I think you'll be better off using std algorithms for carrying our addition/multiplication of vector e.g. use std::transform for adding two vectors or for multiplication
//Add vec1 and vec2 and store the results in result vec
//Note: take care of the ranges of two sources/destination
transform(vec1.begin(), vec1.end(), vec2.begin(), result.begin(), std::plus<int>());
Issues with your code:
returning reference of the local variable
multiply doesn't have a terminating condition.
In C++11, life is easier. Just return by value. It will automatically apply move semantics as opposed to copy semantics. Copying vectors is expensive, but moving them is cheap. Do not bother with pointers or references unless you are willing to profile your code and prove that it is a bottleneck. Using a pointer or reference here obfuscates code, and is a premature optimization.
See this talk: https://www.youtube.com/watch?v=xnqTKD8uD64. He takes up this exact issue, and recommends return by value for any type that is cheap to move.
Edit: when I say don't bother with references/pointers, I mean for returning. Passing in a const ref to a vector for input arguments, and a non-const ref to a vector for an in/out argument, is standard and good practice.