Why does bind not work with pass by reference? [duplicate] - c++

This question already has answers here:
std::bind lose reference when delivered as rvalue reference
(2 answers)
Closed 7 years ago.
I find pass by reference tends not to work when using std::bind. Here's an example.
int test;
void inc(int &i)
{
i++;
}
int main() {
test = 0;
auto i = bind(inc, test);
i();
cout<<test<<endl; // Outputs 0, should be 1
inc(test);
cout<<test<<endl; // Outputs 1
return 0;
}
Why isn't the variable incrementing when called via the function created with std bind?

std::bind copies the argument provided, then it passes the copy to your function. In order to pass a reference to bind you need to use std::ref:auto i = bind(inc, std::ref(test));

Related

Preventing preservation of constness of captured variables in C++ lambdas capturing by value [duplicate]

This question already has answers here:
Implicit type in lambda capture
(2 answers)
C++ confusing closure captures [v] vs [v = v]
(2 answers)
What mechanism prevents captured variables from being moved?
(1 answer)
Closed 7 months ago.
Consider the following case: the second static_assert fails (https://gcc.godbolt.org/z/KP4zxvY7G).
#include <cstdio>
#include <type_traits>
#include <vector>
std::vector<int> generate_numbers();
int main()
{
// Ok
{
std::vector<int> f = generate_numbers();
auto lambda = [=] { printf("%d", (int)f.size()); };
static_assert(std::is_nothrow_move_constructible_v<decltype(lambda)>);
}
// Not good
{
const std::vector<int>& f = generate_numbers();
auto lambda = [=] { printf("%d", (int)f.size()); };
static_assert(std::is_nothrow_move_constructible_v<decltype(lambda)>);
}
}
I would expect both static_assert to pass as making a copy of a const value in my mind creates a new value which does not need to preserve the constness.
But this is not what seems to happen, which is actually problematic in generic code where one may want to rely on lifetime-extension to prevent unneeded copies:
void f(auto&& foo) {
const auto& result = foo();
...
}
What can be done here ? I can use C++20.

Changing values of class instances in a function [duplicate]

This question already has answers here:
Pass by reference and value in C++
(5 answers)
Closed 5 years ago.
I wrote the folloing code to test how to change values of class object in a function.
using namespace std;
class test{
public:
int a;
};
void runer(test testXX){
testXX.a=10;
}
int main()
{
test test1;
test1.a=5;
runer(test1);
cout<<test1.a;
return 0;
}
When I run the following code the output is 5 and not 10. Is it because I can't change the values of class instances, like I can't change the values of array members without using pointers? I would be grateful if someone could clarify that!
void runer(test testXX){
testXX.a=10;
}
Takes a full copy of the type test, so it is modified in the function, but a different instance to the one in main.
Parameters in C++ are sent by value. The simplest example which makes sense is
int function( int value ) {
for( ; value > 0 ; value-- ){
cout << "Hello\n";
}
}
int main( int , char ** ){
int value = 10;
function( value ); // display 10 things
function( value ); // display 10 things again (not modified).
function( 5 ); // also not making sense, if parameter is modified.
}
To allow objects to be modified, they need to be sent as references, or pointers. This allows the value of the item to be changed. The literal 5 can not be sent to a function expecting a reference.
void runer(test & testXX){
testXX.a=10;
}
Now the same object is sent from main to runner, and modifications are done to the single object.
You are passing the argument to the function by value, so it gets a local copy that only lives as long as the scope of the function.
If you want the function to be able to modify the original object that you pass in, then pass it by non-const reference void runer(test& testXX) .
Your code makes a call by value. Hence, the change doesn't appear in the actual object. To change the value of the attribute of the object you need to make a call by reference.
void runer(test &t){
t.a = 10;
}

Why does calling a functor with an undeclared variable work? [duplicate]

This question already has answers here:
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
class foo {
public:
bool operator () (int & i) {
return true;
}
};
int main() {
foo(WhyDoesThisCompile);
return 0;
}
When passing WhyDoesThisCompile (without spaces) to the functor, the program compiles.
Why is this? I tested it on clang 4.0.0.
You are not invoking the functor.
You are declaring a foo, called WhyDoesThisCompile.
Yes, despite the parentheses.
I guess you meant this:
foo()(WhyDoesThisCompile);
// ^^^^^
// temp ^^^^^^^^^^^^^^^^^^^^
// of invocation of op()
// type
// `foo`
… which doesn't.

c++ oop program doesn't give expected result [duplicate]

This question already has answers here:
Returning a reference to a local variable in C++
(3 answers)
Closed 6 years ago.
Consider the following piece of program:
class cls
{
int vi;
public:
cls(int v=37)
{
vi=v;
}
friend int& f(cls);
};
int& f(cls c)
{
return c.vi;
}
int main()
{
const cls d(15);
f(d)=8;
cout<<f(d);
return 0;
}
When I run it, the output is
15
but I don't understand why 15, because I thought it should've outputed 8, because of the
f(d)=8
function, which from what I understand makes the c.vi=8, but I might be wrong and the function probably does something else entirely, so then I ask, what is the purpose or what does the
friend int& f(cls);
function do?
Your program has Undefined Behavior - you are returning a dangling reference to local variable of a function (argument is a local variable as well).

Why does the following closure not work? [duplicate]

This question already has answers here:
What happens if I capture a local variable by reference, and it goes out of scope?
(2 answers)
Closed 8 years ago.
Consider the following code.
#include <functional>
#include <stdio.h>
#include <stdlib.h>
std::function<void()> getFunction() {
int foo = 0;
return [&] () {
printf("foo = %d\n", foo);
};
}
int main(){
std::function<void()> foo = getFunction();
foo();
}
On my machine, it prints the following.
foo = 32767
Why does it not print 0?
It turns out, after consulting one of the other students in my lab, that if you want to capture a variable in a closure by reference, you must ensure that the said variable is still in scope at the time you try to access it. In particular, this means that you can pass a closure to a function call from the function getFunction() but not return it to another function. The closure above has an equivalent problem to returning a local variable by pointer.
Instead, one can use the value-capturing closure, although that means that the captured variables are read-only.
std::function<void()> getFunction() {
int foo = 0;
return [=] () { // Capture by value works
printf("foo = %d\n", foo);
};
}