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..
Related
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 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)
What's the real difference between a foreach and for loop if either can get the same job done? I'm learning C++ and apparently there is no foreach loop for its arrays :(
There is no "foreach" language construct in C++, a least not literally. C++11 introduces something that's "as good as" a foreach loop, though.
The traditional for loop has something to do with evaluating conditions and performing repeated operations. It's a very general control structure. Its most popular use is to iterate over container or array contents, but that's just a tiny fraction of what you can do with it.
A "foreach" loop, on the other hand, is explicitly designed to iterate over container elements.
Example:
int arr[5] = { 1, 3, 5, 2, 4 };
for (int & n : arr) { n *= 2; } // "for-each" loop, new in C++11
for (size_t i = 0; i != 5; ++i) { arr[i] *= 2; } // "classic" for loop
In the second for, we use a traditional for loop to increment an auxiliary variable i in order to access the container arr. The first, range-based loop does not expose any details of the iteration, but just says "do this and that to each element in the collection".
Since the traditional for loop is a very general control structure, it can also be used in unusual ways:
std::vector<std::string> all_lines;
for (std::string line; std::cin >> line; all_lines.push_back(line))
{
std::cout << "On line " << (all_lines.size() + 1) << " you said: " << line << std::endl;
}
You can trivially rewrite for(A; B; C) as a while loop:
{ // scope!
A;
while (true && B)
{
{ // more scope!
/* for loop body */
}
C;
}
}
Edit: I would probably be remiss not to mention the library function template std::for_each from <algorithm>, which in conjunction with lambdas is a very nice and self-descriptive way to iterate over arbitrary ranges (not just entire containers). It has existed since Day 1, but before lambdas it was a show-stopping pain to use.
Update: I thought of something else that might be relevant here: A "foreach" loop generally assumes that you don't modify the container. A common type of looping that modifies the container requires the traditional for-loop; as for example in this typical erase pattern:
for(Container::const_iterator it = v.begin(); it != v.end() /* not hoisted! */; /* no increment */ )
{
// do something
if (suitable_condition)
{
v.erase(it++); // or it = v.erase(it), depending on container type
}
else
{
++it;
}
}
foreach generally has 1 parameter, for has 3. Anything foreach can do for can too. Part of the reason why foreach doesn't exist in C++ is because the number of iterations can't always be inferred from the type.
I believe boost library has a method of getting foreach to work, and C++11 has a range-based of for:
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
x *= 2;
}
There is something like for each for arrays in C++ and that is iterators. Both loops are essentially identical with the only difference being - with an ordinary for loop you have an index which you might need depending on what type of data you are accessing and whether you need to do some calculations with the index and there is (probably) an increased chance of off-by-one errors. Whereas foreach loops just guarantee that will be executed as many times as there are elements in the array without exposing an index (which you can mimic) so as a I said they are essentially the same but their usage largely depends on the way you manipulate your data.
"For Each" syntax is used to iterate through a collection of objects, while a for loop is a loop that will execute for a given range. C++ does have for_each in its STL and can be used to iterate through linear object containers such as a vector.
In other languages with a foreach construct, they're usually convenience for not having to index into the collection you're looping over. That is, you're given the next object in the collection without having access to (or need for) the index itself. If you need the index for some reason, you'll usually need the for loop, though in some languages you have access to the counter in their 'foreach'.
as experience test , FOR is more Faster than FOREACH
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.
I have a std::map that I'm using to store values for x and y coordinates. My data is very sparse, so I don't want to use arrays or vectors, which would result in a massive waste of memory. My data ranges from -250000 to 250000, but I'll only have a few thousand points at the most.
Currently I'm creating a std::string with the two coordinates (i.e. "12x45") and using it as a key. This doesn't seem like the best way to do it.
My other thoughts were to use an int64 and shove the two int32s into it and use it as a key.
Or to use a class with the two coordinates. What are the requirements on a class that is to be used as the key?
What is the best way to do this? I'd rather not use a map of maps.
Use std::pair<int32,int32> for the key:
std::map<std::pair<int,int>, int> myMap;
myMap[std::make_pair(10,20)] = 25;
std::cout << myMap[std::make_pair(10,20)] << std::endl;
I usually solve this kind of problem like this:
struct Point {
int x;
int y;
};
inline bool operator<(const Point& p1, const Point& p2) {
if (p1.x != p2.x) {
return p1.x < p2.x;
} else {
return p1.y < p2.y;
}
}
Boost has a map container that uses one or more indices.
Multi Index Map
What are the requirements on a class that is to be used as the key?
The map needs to be able to tell whether one key's value is less than another key's value: by default this means that (key1 < key2) must be a valid boolean expression, i.e. that the key type should implement the 'less than' operator.
The map template also implements an overloaded constructor which lets you pass-in a reference to a function object of type key_compare, which can implement the comparison operator: so that alternatively the comparison can be implemented as a method of this external function object, instead of needing to be baked in to whatever type your key is of.
This will stuff multiple integer keys into a large integer, in this case, an _int64. It compares as an _int64, AKA long long (The ugliest type declaration ever. short short short short, would only be slightly less elegant. 10 years ago it was called vlong. Much better. So much for "progress"), so no comparison function is needed.
#define ULNG unsigned long
#define BYTE unsigned char
#define LLNG long long
#define ULLNG unsigned long long
// --------------------------------------------------------------------------
ULLNG PackGUID(ULNG SN, ULNG PID, BYTE NodeId) {
ULLNG CompKey=0;
PID = (PID << 8) + NodeId;
CompKey = ((ULLNG)CallSN << 32) + PID;
return CompKey;
}
Having provided this answer, I doubt this is going to work for you, as you need two separate and distinct keys to navigate with in 2 dimensions, X and Y.
On the other hand, if you already have the XY coordinate, and just want to associate a value with that key, then this works spectacularly, because an _int64 compare takes the same time as any other integer compare on Intel X86 chips - 1 clock.
In this case, the compare is 3X as fast on this synthetic key, vs a triple compound key.
If using this to create a sparsely populated spreadsheet, I would RX using 2 distinct trees, one nested inside the other. Make the Y dimension "the boss", and search Y space first to resolution before proceeding to the X dimension. Spreadsheets are taller than they are wide, and you always want the 1st dimension in any compound key to have the largest number of unique values.
This arrangement would create a map for the Y dimension that would have a map for the X dimension as it's data. When you get to a leaf in the Y dimension, you start searching it's X dimension for the column in the spreadsheet.
If you want to create a very powerful spreadsheet system, add a Z dimension in the same way, and use that for, as an example, organizational units. This is the basis for a very powerful budgeting/forecasting/accounting system, one which allows admin units to have lots of gory detail accounts to track admin expenses and such, and not have those accounts take up space for line units which have their own kinds of detail to track.
I think for your use case, std::pair, as suggested in David Norman's answer, is the best solution. However, since C++11 you can also use std::tuple. Tuples are useful if you have more than two keys, for example if you have 3D coordinates (i.e. x, y, and z). Then you don't have to nest pairs or define a comparator for a struct. But for your specific use case, the code could be written as follows:
int main() {
using tup_t = std::tuple<int, int>;
std::map<tup_t, int> m;
m[std::make_tuple(78, 26)] = 476;
tup_t t = { 12, 45 }; m[t] = 102;
for (auto const &kv : m)
std::cout << "{ " << std::get<0>(kv.first) << ", "
<< std::get<1>(kv.first) << " } => " << kv.second << std::endl;
return 0;
}
Output:
{ 12, 45 } => 102
{ 78, 26 } => 476
Note: Since C++17 working with tuples has become easier, espcially if you want to access multiple elements simultaneously.
For example, if you use structured binding, you can print the tuple as follows:
for (auto const &[k, v] : m) {
auto [x, y] = k;
std::cout << "{ " << x << ", " << y << " } => " << v << std::endl;
}
Code on Coliru
Use std::pair. Better even use QHash<QPair<int,int>,int> if you have many of such mappings.
Hope you will find it useful:
map<int, map<int, int>> troyka = { {4, {{5,6}} } };
troyka[4][5] = 7;
An alternative for the top result that is slightly less performant but allows for easier indexing
std::map<int, std::map<int,int>> myMap;
myMap[10][20] = 25;
std::cout << myMap[10][20] << std::endl;
First and foremost, ditch the string and use 2 ints, which you may well have done by now. Kudos for figuring out that a tree is the best way to implement a sparse matrix. Usually a magnet for bad implementations it seems.
FYI, a triple compound key works too, and I assume a pair of pairs as well.
It makes for some ugly sub-scripting though, so a little macro magic will make your life easier. I left this one general purpose, but type-casting the arguments in the macro is a good idea if you create macros for specific maps. The TresKey12 is tested and running fine. QuadKeys should also work.
NOTE: As long as your key parts are basic data types you DON'T need to write anything more. AKA, no need to fret about comparison functions. The STL has you covered. Just code it up and let it rip.
using namespace std; // save some typing
#define DosKeys(x,y) std::make_pair(std::make_pair(x,y))
#define TresKeys12(x,y,z) std::make_pair(x,std::make_pair(y,z))
#define TresKeys21(x,y,z) std::make_pair(std::make_pair(x,y),z))
#define QuadKeys(w,x,y,z) std::make_pair(std::make_pair(w,x),std::make_pair(y,z))
map<pair<INT, pair<ULLNG, ULLNG>>, pIC_MESSAGE> MapMe;
MapMe[TresKey12(Part1, Part2, Part3)] = new fooObject;
If someone wants to impress me, show me how to make a compare operator for TresKeys that doesn't rely on nesting pairs so I can use a single struct with 3 members and use a comparison function.
PS: TresKey12 gave me problems with a map declared as pair,z as it makes x,pair, and those two don't play nice. Not a problem for DosKeys, or QuadKeys. If it's a hot summer Friday though, you may find an unexpected side-effect of typing in DosEquis
... err.. DosKeys a bunch of times, is a thirst for Mexican beer. Caveat Emptor. As Sheldon Cooper says, "What's life without whimsy?".