why can't I send object by reference using std::thread [duplicate] - c++

This question already has an answer here:
Why does passing object reference arguments to thread function fails to compile?
(1 answer)
Closed 7 years ago.
My code goes like this :-
#include <iostream>
#include <thread>
using namespace std;
void swapno (int &a, int &b)
{
int temp=a;
a=b;
b=temp;
}
int main()
{
int x=5, y=7;
cout << "x = " << x << "\ty = " << y << "\n";
thread t (swapno, x, y);
t.join();
cout << "x = " << x << "\ty = " << y << "\n";
return 0;
}
This code fails to compile. Can anyone help me out why ?
Not only this code but the code in this also failed to send std::unique_ptr by reference. What's wrong with std::thread ?

The problem is that std::thread copies its arguments and stores them internally. If you want to pass an argument by reference you need to use the std::ref or std::cref functions to create reference wrappers.
Like
thread t (swapno, std::ref(x), std::ref(y));

You can do this, instead:
#include <iostream>
#include <thread>
void swapno (int *a, int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int x = 5, y = 7;
std::cout << "x = " << x << "\ty = " << y << "\n";
std::thread t (swapno, &x, &y);
t.join();
std::cout << "x = " << x << "\ty = " << y << "\n";
return 0;
}
You should achieve the same result ;)

Related

C++, Pass by Pointers [duplicate]

This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 2 years ago.
I was actually thinking that this program should throw a Compilation Error(coz, I am passing values to swap method and not &a, &b) but I was shocked to see that it got executed Successfully.
So, am posting this to know how/why it got executed without any error.
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x = *y;
*y = z;
}
int main()
{
int a = 45, b = 35;
cout << "Before Swap\n";
cout << "a = " << a << " b = " << b << "\n";
swap(a, b);
cout << "After Swap with pass by pointer\n";
cout << "a = " << a << " b = " << b << "\n";
}
As is said so often on this site, using namespace std; is a bad idea.
You called std::swap<int>

Why cant i swap 2 numbers using static variables if static variables have only one copy stored for the whole part of the program?

If static variables has only one copy for the program. So why is it not possible to swap 2 numbers using another function?
Code:
#include <iostream>
void swap(int, int);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
As the 'swap' function is taking parameters as pass by value, copies of the variables are passed to the swap function which will only swap its local variables 'a' and 'b' (passed as parameter) not the static ones passed from main.
Swap should be taking parameters as references like below.
#include <iostream>
void swap(int&, int&);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
Please note that static variable defined in a function pertains its value in the subsequent calls of the function in which it is declared.
This is because you are passing arguments by value and not by address(reference). Your function is working on a copy of a and a copy of b - not the original values. You could try this(notice the & in the function prototype and function definition arguments)
void swap(int &, int &);
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}

c++ lambda capture by value

I am reading through the C++ lambda section in chapter 3 of this book and the following code confuses me:
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
This code prints out:
x: 0
y: 77
x: 0
y: 78
final y: 79
Why does qqq() not register that x has changed to 77? It was stated that passing by value means we can read but not modify data readable where the lambda was defined. Does that mean we can't see changes after it's definition?
That's because the variable is captured by value (i.e. copied) only once, when you define the lambda. It's not "updated" as you may believe. The code is roughly equivalent to:
#include <iostream>
int x = 0;
struct Lambda
{
int _internal_x; // this is used to "capture" x ONLY ONCE
Lambda(): _internal_x(x) {} // we "capture" it at construction, no updates after
void operator()() const
{
std::cout << _internal_x << std::endl;
}
} qqq;
int main()
{
qqq();
x = 77; // this has no effect on the internal state of the lambda
qqq();
}
Live on Coliru
By binding a variable by value to a lambda closure, you're effectively copying the value of the variable into a separate variable that is found inside the lambda object. Likewise, by binding a variable by reference, you're making such an internal variable to be a reference to the original variable instead, thus being able to "see changes" on the original variable.
Look at it like this. The following code...
#include <iostream>
int main()
{
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
Is (kind of, but not exactly) syntactic sugar for...
#include <iostream>
class MyLambda
{
private:
int x;
int& y;
public:
MyLambda(int x, int& y) : x(x), y(y) {}
void operator()()
{
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
}
};
int main()
{
int x = 0;
int y = 42;
MyLambda qqq = MyLambda(x, y);
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
With the exception of the special lambda syntax and the fact that you can't reference the lambda's type directly. By comparing the former with the later code, you should be able to clear out your understanding of closures.
The lambda uses the value at the time the lambda is defined (it makes a copy), not at the time it is invoked.
This might help: How are Lambda Closures Implemented?

int function parameter not working properly

I'm trying to make something in C++ and I have a problem. I have this code:
#include <iostream>
#include <string>
//---MAIN---
using namespace std;
int af1 = 1;
int af2 = 1;
void lettersort(int cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
}
int main()
{
lettersort(af2);
return 0;
}
So is there any way so that cnt1++ affects af2 too, to make it bigger ? I don't want to use af2++ directly because I want to sometimes use af1.
At the moment you are just passing af2 to cnt1 by value, so any changes to cnt1 are strictly local to the function lettersort. In order to get the behaviour you want you need to pass your cnt1 parameter by reference. Change:
void lettersort(int cnt1)
to:
void lettersort(int &cnt1)
You are passing the argument by value. I.e., you are copying the value of af1 to a local variable in lettersort. This integer is then incremented, and disposed of when the function ends, without affecting the original af1. If you want the function to be able to affect af1, you should pass the argument by reference:
void lettersort(int& cnt1) { // Note the "&"
if i understood your question:
there are 2 ways you can do that.
make lettersort function return the new value, and put it in af2
int lettersort(int cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
return cnt1;
}
int main()
{
af2 = lettersort(af2);
return 0;
}
pass the value by reference. you can read about it here, but generally its about passing a pointer to that value. meaning whatever you do on the argument you are passing, will happen on the original var.
example:
void foo(int &y) // y is now a reference
{
using namespace std;
cout << "y = " << y << endl;
y = 6;
cout << "y = " << y << endl;
} // y is destroyed here
int main()
{
int x = 5;
cout << "x = " << x << endl;
foo(x);
cout << "x = " << x << endl;
return 0;
}
here you have to just modified the argument pass to lettersort
function as passed by reference.
for example if you declare and initialize any variable like:
int a=10; int &b = a;
now a and b refer to the same value.if you change a then the changes
also reflect in b also.
so,
cout << a; cout << b;
both statement produce the same result across the program. so using
this concept i modified the function argument and made it as by
reference.
your correct code is :
#include <iostream>
#include <string>
using namespace std;
int af1 = 1;
int af2 = 1;
void lettersort(int &cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
}
int main()
{
lettersort(af2);
return 0;
}

c++ myVector.erase(myVector.begin()) works but not in my object

How come my ptBucket.getBucket().at(icnt) works but my ptBucket.getBucket().erase() and ptBucket.getBucket().begin() do not work.
Code is below.
I want to have an object that contains a vector of pointers. The pointers will point to dynamically allocated objects and I want to clean up at the end. I seem to be screwing up the extra level of indirection.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Pt{
int x_;
int y_;
public:
Pt(int x, int y);
int getX();
int getY();
};// end class pt
Pt::Pt(int x, int y){
x_ = x;
y_ = y;
}
int Pt::getX(){
return x_;
}
int Pt::getY(){
return y_;
}
class BucketOfPts{
vector<Pt*>bucket;
public:
void addToBucket(Pt *pt);
vector<Pt*> getBucket();
};
void BucketOfPts::addToBucket(Pt *pt){
bucket.push_back(pt);
}
vector<Pt*> BucketOfPts::getBucket(){
return bucket;
}
int main()
{
cout << "this works" << endl;
vector<Pt*> points;
for(unsigned icnt =0;icnt<5;icnt++)
points.push_back(new Pt(icnt,icnt));
for(unsigned icnt =0;icnt<5;icnt++)
cout << "x of icnt["<<icnt<<"] "<< points.at(icnt)->getX() << endl;
for(unsigned icnt =0;icnt<5;icnt++)
{
/*** this simple construct does work ***********/
points.erase(points.begin());
/*** this simple construct does work ***********/
cout << "size: " << points.size() << endl;
}
cout << "this does NOT work" << endl;
BucketOfPts ptBucket = BucketOfPts();
for(unsigned icnt =0;icnt<5;icnt++)
ptBucket.addToBucket(new Pt(icnt,icnt));
for(unsigned icnt =0;icnt<5;icnt++)
cout << "x of icnt["<<icnt<<"] "<< ptBucket.getBucket().at(icnt)->getX() << endl;
// how come ptBucket.getBucket.at() above works
// but ptBucket.getBucket.begin() below does not work??
cout << "going to try to erase" << endl;
for(unsigned icnt =0;icnt<5;icnt++)
{
cout << "going to erase icnt: " << icnt << endl;
/*** this simple construct does NOT work ***********/
ptBucket.getBucket().erase(ptBucket.getBucket().begin());
/*** this simple construct does NOT work ***********/
cout << "size: " << ptBucket.getBucket().size() << endl;
}
return 0;
}
here's my output:
this works
x of icnt[0] 0
x of icnt[1] 1
x of icnt[2] 2
x of icnt[3] 3
x of icnt[4] 4
size: 4
size: 3
size: 2
size: 1
size: 0
this does NOT work
x of icnt[0] 0
x of icnt[1] 1
x of icnt[2] 2
x of icnt[3] 3
x of icnt[4] 4
going to try to erase
going to erase icnt: 0
Segmentation fault (core dumped)
As is, your getBucket() function returns a copy of the vector<Pt*> bucket; member. Thus the statement
ptBucket.getBucket().erase(ptBucket.getBucket().begin());
just operates with two unrelated copies of that vector.
To get the vector member in the class instance affected, you need to return a reference to this member
class BucketOfPts{
public:
// ...
vector<Pt*>& getBucket();
// ^ <<<<<<
};
vector<Pt*>& BucketOfPts::getBucket() {
// ^ <<<<<<
return bucket;
}
`