It is possible to store and wrap member functions with std::mem_fn.
In C you can use offsetof(...) on a member variable to crudely wrap a member variable (but only on a some types).
Is it possible to wrap a member variable in C++? What's the cleanest way?
ie
class X
{
...
M m;
...
};
mem_var<M> xm = &X::m;
int main()
{
X x = ...;
M i = ...;
xm(x) = i; // same as x.m = i
cout << xm(x); // same as cout << x.m
}
Yes, you can do it with... std::mem_fn.
struct B
{
int x;
int y;
};
int main()
{
auto m = std::mem_fn(&B::y);
B b {0, 0};
m(b) = 4;
printf("%d %d\n", b.x, b.y); // prints 0 4
printf("%d\n", m(b)); // prints 4
return 0;
}
Demo: http://ideone.com/40nI2
Related
Could anybody explains to me why the result is 2, which x is using and why.
auto x = 0;
int f(int i){
auto x = 1;
{
static auto x = 0;
x += i;
}
return x;
}
int main() {
cout << f(1) + f(2) <<endl;// result 2
return 0;
}
The inner x shadows the outer one, but the mutations only apply to the inner most scope
int f(int i){
auto x = 1; // consider this "x1"
{
static auto x = 0; // this is "x2"
x += i; // mutates "x2" but not "x1"
}
return x; // return "x1" which is still 1
}
Therefore
f(1) + f(2) // 1 + 1 == 2
This is all about variable shadowing.
The innermost x in function f is shadowing the automatic x in that function. So that function is equivalent to
int f(int){
auto x = 1;
return x;
}
Note furthermore that the x in my abridged version shadows the one at global scope.
The function f is further abbreviated to
int f(int){
return 1;
}
and now the program output should be obvious.
In fact this function
int f(int i){
auto x = 1;
{
static auto x = 0;
x += i;
}
return x;
}
can be rewritten like
int f(int i){
auto x = 1;
return x;
}
because the static variable x declared in this block scope
{
static auto x = 0;
x += i;
}
is not used outside the block and does not influence on the returned value of the function. The only side effect of this code block is potential overflowing of the static signed integer variable x that has undefined behavior.
So the both function calls f(1) and f(2) returns 1 and as a result the expression f(1) + f(2) yields 2.
In the program there are declared three variables x. The first one in the global name space
auto x = 0;
The second one in the outer-most block of the function f that hides the declaration of the variable x in the global name space.
auto x = 1;
And the third one is declared in an inner block of the function f
{
static auto x = 0;
x += i;
}
that is not visible outside this inner block.
I have a problem with my code. It is intended to save the values into a struct array. But 2 things happen at random - 1) Array may be empty or 2) Array may contain only one row of values.
struct MacroMas
{
int x;
int y;
int Delay;
int SemiAutoDelay;
int ammo;
MacroMas* Cords(int x, int y, int Delay)
{
MacroMas _ret;
_ret.x = x;
_ret.y = y;
_ret.Delay = Delay;
return _ret;
}
};
MacroMas* temp()
{
MacroMas _ret;
MacroMas* macroMasArray = new MacroMas[107];
for (int index = 0; index <107 ; ++index)
macroMasArray[index] = MacroMas();
macroMasArray[0].Cords(-3, 4, 16);
macroMasArray[1].Cords(-3, 4, 17);
// Some more code
return macroMasArray;
First in Cords function : function will return MacroMas* and you return an object of type MacroMas it's mistake in your Code.
in these two lines you make a mistake
macroMasArray[0].Cords(-3, 4, 16);
macroMasArray[1].Cords(-3, 4, 17);
Cords function has return value
When macroMasArray[0] or [1] calls Cords its not affect on them.
you need to store them like
macroMasArray[0] = macroMasArray[0].Cords(-3, 4, 16);
or use this pointer in the Cords Body.
void Cords(int x, int y, int Delay)
{
this->x = x
this->y = y;
this->Delay = Delay;
}
This question already has answers here:
Scope of variables in if statements
(4 answers)
Closed 3 years ago.
I have two variables and I want to work with the bigger and the smaller one differently.
My approach:
a = 1;
b = 2;
if (a >= b){
int c = a;
int d = b;
}
else{
int c = b;
int d = a;
}
I obtained an error of unused variable and when I try to use c and d later, it says
c could not be resolved
Is there a way to solve this?
In both cases c and d are scoped to the braces in the if else block, so you can't access them outside that.
You need something of the form
int c, d;
if (a >= b){
c = a;
d = b;
} else {
c = b;
d = a;
}
As other have pointed out the issue here is where you declare the variables. You cannot use them outside of the scope they are declared in so you get an error.
If you can use C++17 then you can fix the code by using std::minmax and a structured binding like
int main()
{
int a = 5, b = 10;
auto [min, max] = std::minmax(b, a);
std::cout << min << " " << max;
}
which is really nice because now you don't have variables that are uninitialized for any amount of time.
It's because you are declaring the variables in an if statement.
Logically you may be of the belief that the else in a way guarantees that the variables will be assigned if the declaration is in both the if and also in the else block.
The correct way to do it is to just declare the variables before the if block, otherwise the variables use will be restricted to the scope from which it was declared.
Also, you can do this without the need for an if and else by using ternary operations:
int a = 1;
int b = 2;
int c = a >= b ? a : b;
int d = b < a ? b : a;
With this type of syntax, you can save yourself the hassle of writing if and else blocks for simple variable assignments. The variable after the ? is the result if the condition is true, and the variable after the : is the result if the condition is false.
That's a scope problem, you are creating the variables inside a scope and they can't be accessed outside
if (a >= b){
int c = a; // c and d belongs to that if scope
int d = b;
}
else{
int c = b; // c and d belongs to that else scope
int d = a;
}
Change your code to this :
a = 1;
b = 2;
int c;
int d;
if (a >= b){
c = a;
d = b;
}
else{
c = b;
d = a;
}
// You can now call c and d there
A way to shorten that code would be to store the boolean value of a >= b and use it in a ternary expression to set c and d
In example :
a = 1;
b = 2;
bool IsAGreaterOrEqualToB = (a >= b);
int c = ((IsAGreaterOrEqualToB) ? (a) : (b));
int d = ((IsAGreaterOrEqualToB) ? (b) : (a));
I'm pretty new to C++ and I have the following simple program:
int main()
{
int a = 5,b = 10;
int sum = a + b;
b = 6;
cout << sum; // outputs 15
return 0;
}
I receive always the output 15, although I've changed the value of b to 6.
Thanks in advance for your answers!
Execution of your code is linear from top to bottom.
You modify b after you initialize sum. This modification doesn't automatically alter previously executed code.
int sum = a + b; writes the result of adding a and b into the new variable sum. It doesn't make sum an expression that always equals the result of the addition.
There are already answers, but I feel that something is missing...
When you make an assignment like
sum = a + b;
then the values of a and b are used to calculate the sum. This is the reason why a later change of one of the values does not change the sum.
However, since C++11 there actually is a way to make your code behave the way you expect:
#include <iostream>
int main() {
int a = 5,b = 10;
auto sum = [&](){return a + b;};
b = 6;
std::cout << sum();
return 0;
}
This will print :
11
This line
auto sum = [&](){return a + b;};
declares a lambda. I cannot give a selfcontained explanation of lambdas here, but only some handwavy hints. After this line, when you write sum() then a and b are used to calculate the sum. Because a and b are captured by reference (thats the meaning of the &), sum() uses the current values of a and b and not the ones they had when you declared the lambda. So the code above is more or less equivalent to
int sum(int a, int b){ return a+b;}
int main() {
int a = 5,b = 10;
b = 6;
std::cout << sum(a,b);
return 0;
}
You updated the b value but not assigned to sum variable.
int main()
{
int a = 5,b = 10;
int sum = a + b;
b = 6;
sum = a + b;
cout << sum; // outputs 11
return 0;
}
I know this has been asked before but I still don't know how to do it. I Have to write a function which returns the number of times 2, 5 and 9 appear in an array.
include <iostream>
int twofivenine(int array[], int n)
{
int i = 0;
int num_2 = 0;
int num_5 = 0;
int num_9 = 0;
for ( i = 0; i < n; i++ ){
switch(){
case (array[i] == 2):
num_2++;
case (array[i] == 5):
num_5++;
case (array[i] == 9):
num_9++;
}
}
return ;
}
int main()
{
int array[6] = {2,2,3,5,9,9};
std::cout << "2: 5: 9:" << twofivenine(array, 6) << std::endl;
}
I'm just not sure how to return (num_2, num_5, and num_9)
Can use std::tuple
std::tuple<int, int, int > twofivenine( int array[], int n)
{
//
return make_tuple( num_2, num_5, num_9 );
}
auto x = twofivenine( array, 6 );
std::cout << std::get<0>( x ) << '\n'
<< std::get<1>( x ) << '\n'
<< std::get<2>( x ) << '\n' ;
There are a number of ways to approach this problem.
Pass the values by reference. You can call a function such as the following:
Example:
void foo(int &a, int &b, int &c)
{
// modify a, b, and c here
a = 3
b = 38
c = 18
}
int first = 12;
int second = 3;
int third = 27;
foo(first, second, third);
// after calling the function above, first = 3, second = 38, third = 18
Store the values to return in a data type. Use a data type from the standard library such as std::vector, std::set, std::tuple, etc. to hold your values then return that entire data member.
Example:
std::vector<int> foo()
{
std::vector<int> myData;
myData.pushBack(3);
myData.pushBack(14);
myData.pushBack(6);
return myData;
}
// this function returns a vector that contains 3, 14, and 6
Create an object to hold your values. Create an object such as a struct or a class to hold your values and return the object in your function.
Example:
struct myStruct
{
int a;
int b;
int c;
};
myStruct foo()
{
// code here that modifies elements of myStruct
myStruct.a = 13;
myStruct.b = 2;
myStruct.c = 29;
return myStruct;
}
// this function returns a struct with data members a = 13, b = 2, and c = 29
The method you choose will ultimately depend on the situation.
Pass objects in by reference, ie
void twofivenine(int array[], int n, int &num_2, int &num_5, int &num_9)
{
//Don't redeclare num_2...
}
Call like so:
int num_2, num_5, num_9;
twofivenine(array, 6, num_2, num_5, num_9);
Return a struct by value which has the counts as the data members:
struct Result {
int num_3;
int num_5;
int num_9;
};
Result twofivenine(int array[], int n)
{
.
.
.
return Result{num_2, num_5, num_9};
}
and in main:
Result result(twofivenine(array, 6));
std::cout << "2: " << result.num_2 << "5: " << result.num_5 << "9: " << result.num_9 << std::endl;
Most compilers will do RVO (return-value-optimization) where the twofivenine function will directly write to the result struct avoiding a struct copy.