I have two integer variables i and j and I want to make a function which takes these two variables as its argument and interchanges their contents using xor operator. Now if I make the function to take arguments by value i.e void swap (int x , int y);(with function body same as for the function swap below) then the values are being swapped nicely within the function. But as what I want is the swapping of the values of the variables in the calling function I used passing arguments by reference (and by pointers as well) :
void swap ( int& x , int& y )
{
x^=y^=x^=y;
cout << x<< " " << y << endl ;
}
int main ()
{
int i (1), j (2) ;
swap ( i, j ) ;
cout << i << " " << j << endl ;
}
but neither case showed the correct result !
Why is the swap function not swapping the values on passing arguments by reference or pointers ?
I have two integer variables i and j and I want to make a function
which takes these two variables as its argument and interchanges their
contents using xor operator.
Why?
As you've figured out, you need either to pass pointers to the objects, or to use references.
This:
x^=y^=x^=y;
has undefined behavior, since it modifies the same object twice between sequence points (it does this for both x and y).
The xor trick fails if both objects are the same object; the first xor zeros the object.
If you want to swap two objects, just use a temporary:
int temp = x;
x = y;
y = temp;
It's simple, and it works.
As others have noted, this is a pretty silly optimization (if you can call it that). The problem is the chained use of in-place operators. Broken it into separable statements, it works.
x^=y; // values are X^Y, Y
y^=x; // values are X^Y, X
x^=y; // values are Y, X
Like the others, I would encourage you not to riddle your code with such clarity-killing cleverness unless you have a demonstrable need established by profiling and a demonstrable speedup for doing your bit twiddling hack. (cool site)
Related
I have vector of integers filled with 5 numbers and i'm curious what exactly does [&idx] do in :
int idx = 0;
for_each ( x . begin (), x . end (), [&idx] ( const int & a ) { cout << idx ++ << " " << a << endl; } );`
Why it does not work like this ? :
int idx = 0;
for_each ( x . begin (), x . end (), ( const int & a, int & idx ) { cout << idx ++ << " " << a << endl; } );
Is it better from perfomance point of view than? :
for ( vector<int>::size_type i = 0; i < x . size (); i ++ )
cout << x[i] << endl;
I'm curious what exactly does [&idx] do
That's the lambda capture. It sets the lambda to take a reference to idx. It won't work as a parameter because for_each only passes one parameter to the predicate. If you made idx a parameter instead, it wouldn't compile.
Also is it better from a performance point of view?
Possibly. If you really want to know, test each way of doing it.
what exactly does [&idx] do in
the
[](){}
structure, as of C++11, is a lambda function - that is, an anonymous function which, in this context, will be callbacked with the vector elements passed as arguments. The [&idx] denotes that the variable idx which DOES NOT NORMALLY BELONG to the lambda's environment and which is NORMALLY INACCESSIBLE by the latter, should be instead accessible (captured) in it by reference. This means that you can use idx within the body of the lambda and that whenever you do so you are using a reference to the original variable. Therefore, the idx++ part of the code increments the original idx variable and not some local copy.
Why it does not work like this ?
because () {} structures are not a valid C++ expressions or statements.
Is it better from perfomance point of view than? :
Probably, but not necessarily, you should measure to find out for sure. However, it is both advisable and idiomatic to use iterators and algorithms rather than C-style loops. Given the standard "avoid premature optimisation" guideline, I suggest that you use the first version by default and when you're done with all development you can decide if you want to dedicate some time to try-out and measure alternatives such as the second. If this is not in some critical part of your program (such as in some callback function), I don't think it deserve the fuss, the difference would be very small anyway.
Just for reference, in my system, using clang++ with -O3 flag, 1000 iterations of your std::foreach version would last 4967ms while 1000 of the for one 3861ms. That's approximately 1second for 1000 iterations, e.g. 1ms if you only run this code once..
As a course project, I am building a lottery machine simulator with different kinds of prizes.
I have a class called LotteryTicket which holds a vector<int> luckyNumbers as one of its private member variables. In order to access it, I have defined a get function as following:
vector<int> LotteryTicket::getLuckyNumbersList()
{
return luckyNumbers;
}
One of the things I am required to do is check for winning tickets. A "Bronze" winner is someone who managed to guess all the correct numbers, but not in the correct order. In other words, the sets have to match. In order to do that, I want to sort both tickets (the winning numbers and the player's numbers) and then check 1 for 1.
I attempt to sort them by using the following functions:
void LotteryMachine::sortTicket(LotteryTicket& ticket)
{
for(int i = ticket.getLuckyNumbersList().size()-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(ticket.getLuckyNumbersList()[j] > ticket.getLuckyNumbersList()[j+1])
swap(ticket.getLuckyNumbersList()[j], ticket.getLuckyNumbersList()[j+1]);
}
}
cout << endl << "Sorted ticket " << ticket.getTicketNumber() << ":";
printTicket(ticket);
}
//sorting by bitwise operations
void LotteryMachine::swap(int& a, int& b)
{
a ^= b;
b ^= a;
a ^= b;
}
I have the cout there as a test to see if my vectors were indeed sorted. So far no luck. I am suspecting I'm losing reference at some point, but I'm not sure where... or I might messed something up in my syntax with all these long dot-notation returns...
For additional context, the sortTicket(LotteryTicket&) function is invoked from within the function that checks if a ticket is a bronze winner. That mentioned function receives the ticket argument from a different function... i.e. a long chain of passing the argument, all with a call by reference (I can paste more code if needed.)
Any thoughts? The sortTicket function should sort the arrays and make it stick outside the scope of the function.
vector<int> LotteryTicket::getLuckyNumbersList()
You made a copy when getLuckyNumbersList() returns since you weren't returning a reference.
Change into the following instead.
vector<int>& LotteryTicket::getLuckyNumbersList()
1) I want to pass a the pointer of a QVector to a function and then do things with it. I tried this:
void MainWindow::createLinearVector(QVector<float> *vector, float min, float max )
{
float elementDiff=(max-min)/(vector->size()-1);
if(max>min) min -= elementDiff;
else min += elementDiff;
for(int i=0; i< vector->size()+1 ; i++ )
{
min += elementDiff;
*(vector+i) = min; //Problematic line
}
}
However the compiler gives me "no match for operator =" for the *(vector+i) = min; line. What could be the best way to perform actions like this on a QVector?
2) The function is supposed to linearly distribute values on the vector for a plot, in a way the matlab : operator works, for instance vector(a:b:c). What is the simpliest and best way to perform such things in Qt?
EDIT:
With help from here the initial problem is solved. :)
I also improved the metod in itself. The precision could be improved a lot by using linear interpolation instead of multiple additions like above. With multiple addition an error is accumulating, which is eliminated in large part by linear interpolation.
Btw, the if statement in the first function was unecessary and possible to remove by just rearranging stuff a little bit even in the multiple addition method.
void MainWindow::createLinearVector(QVector<double> &vector, double min, double max )
{
double range = max-min;
double n = vector.size();
vector[0]=min;
for(int i=1; i< n ; i++ )
{
vector[i] = min+ i/(n-1)*range;
}
}
I considered using some enchanced loop for this, but would it be more practical?
With for instance a foreach loop I would still have to increment some variable for the interpolation right? And also make a conditional for skipping the first element?
I want to place a float a certain place in the QVector.
Then use this:
(*vector)[i] = min; //Problematic line
A vector is a pointer to a QVector, *vector will be a QVector, which can be indiced with [i] like any QVector. However, due to precedence, one needs parentheses to get the order of operations right.
I think, first u need use the Mutable iterator for this stuff: Qt doc link
Something like this:
QMutableVectorIterator<float> i(vector);
i.toBack();
while (i.hasPrevious())
qDebug() << i.{your code}
Right, so it does not make much sense to use a QVector pointer in here. These are the reasons for that:
Using a reference for the method parameter should be more C++'ish if the implicit sharing is not fast enough for you.
Although, most of the cases you would not even need a reference when just passing arguments around without getting the result back in the same argument (i.e. output argument). That is because *QVector is implicitly shared and the copy only happens for the write as per documentation. Luckily, the syntax will be the same for the calling and internal implementation of the method in both cases, so it is easy to change from one to another.
Using smart pointers is preferable instead of raw pointers, but here both are unnecessarily complex solutions in my opinion.
So, I would suggest to refactor your code into this:
void MainWindow::createLinearVector(QVector<float> &vector, float min, float max)
{
float elementDiff = (max-min) / (vector.size()-1);
min += ((max>min) ? (-elementDiff) : elementDiff)
foreach (float f, vector) {
min += elementDiff;
f = min;
}
}
Note that I fixed up the following things in your code:
Reference type parameter as opposed to pointer
"->" member resolution to "." respectively
Ternary operation instead of the unnatural if/else in this case
Qt's foreach instead of low-level indexing in which case your original point becomes moot
This is then how you would invoke the method from the caller:
createLinearVector(vector, fmin, fmax);
I have two integer variables i and j and I want to make a function which takes these two variables as its argument and interchanges their contents using xor operator. Now if I make the function to take arguments by value i.e void swap (int x , int y);(with function body same as for the function swap below) then the values are being swapped nicely within the function. But as what I want is the swapping of the values of the variables in the calling function I used passing arguments by reference (and by pointers as well) :
void swap ( int& x , int& y )
{
x^=y^=x^=y;
cout << x<< " " << y << endl ;
}
int main ()
{
int i (1), j (2) ;
swap ( i, j ) ;
cout << i << " " << j << endl ;
}
but neither case showed the correct result !
Why is the swap function not swapping the values on passing arguments by reference or pointers ?
I have two integer variables i and j and I want to make a function
which takes these two variables as its argument and interchanges their
contents using xor operator.
Why?
As you've figured out, you need either to pass pointers to the objects, or to use references.
This:
x^=y^=x^=y;
has undefined behavior, since it modifies the same object twice between sequence points (it does this for both x and y).
The xor trick fails if both objects are the same object; the first xor zeros the object.
If you want to swap two objects, just use a temporary:
int temp = x;
x = y;
y = temp;
It's simple, and it works.
As others have noted, this is a pretty silly optimization (if you can call it that). The problem is the chained use of in-place operators. Broken it into separable statements, it works.
x^=y; // values are X^Y, Y
y^=x; // values are X^Y, X
x^=y; // values are Y, X
Like the others, I would encourage you not to riddle your code with such clarity-killing cleverness unless you have a demonstrable need established by profiling and a demonstrable speedup for doing your bit twiddling hack. (cool site)
I started to read a book about C++ and found the following code.
It is an example on how you can send pass parameters by reference.
#include <iostream>
void swap(int &x, int &y);
int main()
{
int x = 5, y = 10;
std::cout << "Main. Before swap, x: " << x
<< " y: " << y << "\n";
swap(x, y);
std::cout << "Main. After swap, x: " << x
<< " y: " << y << "\n";
return 0;
}
void swap(int &rx, int &ry)
{
int temp;
std::cout << "Swap. Before swap, rx: " << rx
<< " ry: " << ry << "\n";
temp = rx;
rx = ry;
ry = temp;
std::cout << "Swap. After swap, rx: " << rx
<< " ry: " << ry << "\n";
}
.
Main. Before swap, x:5 y: 10
Swap. Before swap, rx:5 ry:10
Swap. After swap, rx:10 ry:5
Main. After swap, x:10, y:5
The logic is clear to me.
Now this may be a very stupid question (I'm not very experienced yet), but why can't you just declare private: int x as an instance variable? Isn't x in this case directly accessible everywhere in your class? (without the need for specifying parameters at all)? Thanks in advance for your answers!
For several reasons.
You should declare variables at the narrowest scope possible. Why? Look at 2 & 3
Variables are expensive, they take up memory, you only want them
around as long as you need them.
The greater a variables scope (i.e. how much code the variable is visible
to) the greater the chance that you will mistakenly use the
variable, and therefore it's value may change unexpectedly. This will be a bug, good luck hunting that one down.
Tight coupling (this is bad). If you write a class and put a swap method on the
class, and you write it so it uses instance member x (not method
variable x), then that swap method CAN ONLY EVER swap using x, if
in time you need it to swap on a different variable (or the
parameter of another method on the class) then you've to move the
value into x which is Inefficient & goto 5. Isn't it better to call the swap function with the values you have to hand, without needing to know there's a special x variable that you have to set first?
Error prone. Will this second method be called while another method
is using the swap method? What should the value of x be after it's
called? You're introducing lots of context around swap and knowing when it's
ok to call swap, and what can call swap. This is bad, the more self contained any piece of code is, then the less of have to worry about it, and about how it's used.
No other class can re-use your swap method, every class that needs a
swap method must implement it's own, and this is a huge big
no-no for more reasons than I can count here, but can sum up as it
voliates the DRY Principal
All of these problems can be removed by simply passing the values by reference. Bit of a no-brainer really :)
Hope this helps.
Passing values via arguments to a function ensures modularity in your code. It sounds like you're just starting out with C++, so I'm not sure how familiar you are with object oriented programming. Functions/methods represent a layer of encapsulation. Your swap() function should encapsulate the logic needed to perform its function/purpose. The caller should not be concerned with how this is accomplished. If your swap() function must assert there is a global variable available in the program, then it's not fully encapsulating the logic of "swapping".
Also, Lets say you wanted to reuse this function elsewhere in your class. It would be difficult and clumsy to use a set of global variables for calling this function. In addition, you may have other locations in your class that are referencing those global variables, and therefore your other calls to swap() would change those values, potentially causing confusion in other areas of the code.