I've got the following code (vastly simplified):
#include<functional>
std::function<int()> Count() {
int x = 0;
return [=]() mutable { return x++; };
}
std::function<int()> Negate(std::function<int()> x) {
return [=]() { return -x(); };
}
int main() {
std::function<int()> n;
int z = 0;
if (true) {
auto c = Count();
z = c();
n = Negate(c);
z = n();
z = n();
}
z = n();
z = n();
}
My problem is, calls to n only work within the if statement. As soon as the if loses scope, c gets destroyed and n stops working. Is there a sensible way of fixing this? Preferably non-invasively.
Related
Consider the following example:
func(cond, block_A, block_B) {
if(cond) {
block_A; // Run all the statements in the block A
} else {
block_B; // Run all the statements in the block B
}
}
int main() {
block_A = {
y = 1;
std::cout << (y);
// statement continues ...
}
block_B = {
z = 1;
std::cout << (z);
// statement continues ...
}
func(true, block_A, block_C);
}
Is there any way to pass a block of statements as an argument to the function call?
You can pass callables to func and use lambda expressions:
#include <iostream>
template <typename F,typename G>
void func(bool cond, F a, G b) {
if(cond) {
a(); // Run all the statements in the block A
} else {
b(); // Run all the statements in the block B
}
}
int main() {
auto block_A = [](){
int y = 1;
std::cout << y;
};
auto block_B = [](){
int z = 1;
std::cout << z;
};
func(true, block_A, block_B);
}
This is a follow-up question to
mem_fn to function of member object
This is the current code.
#include <vector>
#include <algorithm>
#include <functional>
struct Int
{
Int(int _x = 0) : x(_x) {}
int GetInt() const { return x; }
int x;
};
struct IntWrapper
{
IntWrapper(int _x = 0) : test(_x) {}
int GetWrappedInt() const { return test.GetInt(); }
Int test;
};
template<class ContainerT, class Mem> constexpr auto maxElem(const ContainerT& _container, Mem _Pm)
{
auto memFn = std::mem_fn(_Pm);
return memFn(std::max_element(_container.cbegin(), _container.cend(), [&](auto _rhs, auto _lhs) { return memFn(_rhs) < memFn(_lhs); }));
}
int main()
{
{
std::vector<Int> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
}
{
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 7 % 11); // some random values
}
int m = maxElem(vec, &IntWrapper::GetWrappedInt);
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
}
return 0;
}
The original question was about retrieving the x value of the Int struct through anIntWrapper object. I used mem_fn for this because it doesn't seem to distinguish between a function returning an int and an int member variable (Seen in these lines:
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
The solution for IntWrapper objects was to add .test
auto y = std::mem_fn(&Int::GetInt);
auto b = y(wrapper.test);
to the call. However, in the maxElem function, I cannot do this.
I'm wondering if there is a way to formulate the call in such a way that the mem_fn goes from the IntWrapper object directly to the int x variable (Without the helper function and assuming that all members are public).
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
The original approach was auto y = std::mem_fn(&IntWrapper::test.GetInt); // ERROR, which of course does not compile, but shows the idea.
Thanks in advance!
You cannot use std::mem_fn with something different than a pointer to member (such as a pointer to member of member). So, you must use that. In your particular case, you can achieve that with
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
auto m = maxElem(vec, &IntWrapper::GetWrappedInt);
However, I strongly advise you to use lambda expressions whenever possible. std::mem_fn should be considered as if deprecated, since, AFAIK, it serves no purpose that cannot be achieved at least as well by other means, i.e. a lambda.
I have a class with multiple methods defined. There is one method which simply returns a value from a member variable. There is another method which I would like to 'update' the returned value from the previous method, from inside this method.
Example: (assume declarations for X have already been made in a .hpp file)
A::A() {
X = 800; //constructor initialising x & y
Y = 1;
}
A::funcA() {
return Y;
}
A::funcB() {
if (x > y) {
//make funcA now return 2 ...
}
I can set Y to be the value I want perfectly, but how do I recall funcA to 'update' the value returned with the new value of Y I have set? When I try to call: funcA() == 2; It doesn't seem to update properly.
The simplest method would be to update the value of Y since that is beng returned.
A::A() {
X = 800; //constructor initialising x & y
Y = 1;
}
A::funcA() {
return Y;
}
A::funcB() {
if (x > y) {
Y = 2;
}
Your example lacks a few things like return values and what your return value would be if x
Just decide in funcA() what to return:
int A::funcA(){
if (x > y) {
return Y; // or return 2 or whatever, just an example
return X;
}
Or, have a special 'return value'
class A
{
private:
int X,Y,retA;
public:
A()
{
X = 800; //constructor initialising x & y
Y = 1;
retA=Y;
}
int funcA() {
return retA;
}
funcB() {
if (x > y) {
retA = 2;
}
}
}
You might even go for a pointer, if you want to switch between the two variables. This prevents you from copying the value but does not allow you to return a different value than one of the stored ones.:
class A
{
private:
int X,Y;
int* retA;
public:
A()
{
X = 800; //constructor initialising x & y
Y = 1;
retA=&Y;
}
int funcA() {
return *retA;
}
funcB() {
if (x > y) {
retA = &X;
//do NOT use retA = 2 here, that would be invalid
// *retA = 2 would be possible, but change either X or Y
}
else {
retA = &Y;
}
}
}
The MWE is
#include <iostream>
using namespace std;
class N {
public:
float x;
N() { x = 0.0; }
N(float a) { x = a; }
//N(N &n) { x = n.x; }
N &operator=(float f) { cout << "########";return *new N(f); }
};
int main() {
N a;
a = 3.0;
cout << a.x;
return 0;
}
What I expect is: it prints 3, but it actually prints 0. It seems the value didn't change.
Then I change it into
x = f; return *this;
It worked, why?
Of course it doesn't change. You don't change it in your assignment operator. Instead you return a pointer to a new value allocated on the heap...and ignore that result.
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
In this program, if I use the chaining functions, values of x and y it comes to be : x=10, y=0 instead of x=10 , y=20
If instead of chaining function, I use:
obj1.setX(10) and obj1.setY(20) separately,
x value comes to be 10
y value comes to 20.
Can someone please explain why it is like this.
Your set* methods are returning copies of the Test object.
So when you chain your calls, the setY is applied to the temporary copy, and thrown away.
You can either return a reference on an object:
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { x = b; return *this; }
Or to store copy of changed object:
Test obj1;
Test objCopy = obj1.setX(10).setY(20);
objCopy.print();
First is more efficient due to not copying object.