I have the following code:
#include <iostream>
#include <algorithm>
struct Point
{
int x, y;
Point(int x, int y): x(x), y(y) {}
};
int main()
{
Point arr[] = {
Point(4,2), Point(0,3), Point(1,2)
};
std::sort(arr, arr+sizeof(arr)/sizeof(Point), [](Point a, Point b){return a.x<b.x;});
return 0;
}
Now, i am supposed to write iterative for loop (built in cpp for_each loop) which prints out all of the elements of the array, where, as a iteration variable we must use auto reference.
Now, this confuses me a bit, since i know this can be done without any iteration variables or something, like this:
std::for_each(arr,arr + sizeof(arr)/sizeof(Point), [](Point a){cout<<a.x<<a.y<<std::endl;}
Obviously, this is not what i am asked to do, so, since i never found myself using iteration variables when dealing with for_each loop, i'd like to find out how am i supposed to do that properly, especially considering the fact that i have to use auto reference. Any help appreciated!
If you're looking for a solution based on std::for_each, you can do the following.
std::for_each(std::begin(arr), std::end(arr),
[](auto& p){ cout << p.x << p.y << "\n"; });
// ^^^^^ auto reference
Here, you have an auto& reference for the object that you intend to do something with in each iteration (in the case above, it would make sense to use const auto&).
This is almost identical to the range-based for loop suggested by #cdhowie. The only interesting point to note here is that std::for_each is one of the few (the only?) exception to the rule that callables passed to STL algorithms must not have side effects. In this case, writing to the global std::cout object is a side effect, and std::for_each explicitly allows that.
You're probably looking for the range-for loop:
for (auto & i : arr) {
std::cout << i.x << ',' << i.y << '\n';
}
Related
What would be a better way (performance) to iterate primitive type container with ranged for (for reading elements values) - read elements by ref or by value?
std::vector<int> v;
for (const auto e : v) { std::cout << e; }
or
for (const auto& e : v) { std::cout << e; }
There is:
Is it counter-productive to pass primitive types by reference?
Wondering if these 2 things (passing and iterating by ref and value) might be somehow related.
Another note:
I do recognize what is the difference between access by ref, const-ref and value as well as copying values - I only interested in what way would perform better for READ-ONLY.
For small, primitive types, if you don't want to modify the elements of the container, then it's really a matter of style, although for such 'read-only' access, you're probably safer using the by-value approach (which will actually prevent any unintended modification of the 'originals' - although a const qualifier on the reference will also prevent that).
However, if you do want to modify the contained elements, then you will need to iterate using a reference variable, as shown in the below code sample:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{ 1,2,3,4,5 };
for (auto e : v) ++e; // By value: takes copies
for (auto f : v) std::cout << f << " "; // Elements unchanged
std::cout << std::endl;
for (auto& e : v) ++e; // By reference: refers to actual elements
for (auto f : v) std::cout << f << " "; // Elements incremented
std::cout << std::endl;
// for (const auto& e : v) ++e; // const reference: Compiler error!
return 0;
}
I am not saying that this is the only correct approach, but it is a completely valid approach: Do not worry about performance when writing the code. Care about readability and keep performance for when you have something correct and working.
Taking this as premise my advice is the following:
Use this as default when you do not need to modify the containers elements:
for (const auto& e : v) {}
Only when for some reason you need a copy of the elements (but still do not want to modify the elements) use
void foo(int& x) {}
for (auto e : v) {
e += 5;
foo(e);
}
If you need to modify the elements use a reference:
for (auto& e : v) {}
Last but not least, once you have working correct code and you realized that this loop is a bottneck by measuring: Look at the assembly to see what is better.
However, consider that any non-trivial loop body is likely to outweigh the difference between copying a small type and taking a reference.
In theory, the object variable can potentially be more efficient because it doesn't involve indirection through a reference. However, at least in this simple example the reference version may be optimised to be identical with the object version, so it wouldn't necessarily matter in practice.
Wondering if these 2 things (passing and iterating by ref and value) might be somehow related.
Yes. Same rules of thumb apply to both cases. And in both cases it likely won't matter if everything is inlined by the optimiser.
The following code is fairly similar to my actual application. Basically, I am trying to create a vector of functions so that I can generate a very large output in segments. I don't fully understand how the capture by reference [&] is working / should be working, and it's leading to some weird behavior.
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
template <typename T>
T add(const T& a, const T& b) {
return a + b;
}
template <typename T>
T add(const T& a, const T& b, T x) {
return (add<T>(a,b)*x);
}
int main() {
std::cout << "Hello World!\n";
vector<function<long ()>> funks;
for (long i = 1; i < 12; ++i) {
//auto funky = std::bind(add<int>, i, i*i);
std::cout << "PROOF: " << add(i, i*i, 2L) << std::endl;
function<long ()> funky = [&]() -> long {
long V = i;
return add(V, V*V, 2L);
};
funks.push_back(funky);
}
for (auto&& x : funks) {
std::cout << x() << " ";
}
}
The output of running each x in funks is: [312, 312, 312 ... 312] corresponding to i = 13
However, I don't understand why this is the case, as I reinitialize V for each lambda, and the output should be [4, 12, 24, 40, ... 264]
It works when I change the capture clause to [=], but in my actual application the inputs will be quite large so I'd prefer to copy as few times as possible.
EDIT: I should clarify exactly what I'm looking for. I'd like to make a vector of N functions, [f_0, f_1, ... f_N], such that when calling f_i(), it calls F(V_i) for some large (known) function F and large V_i.
The reason I want to capture by reference is that I don't want to copy the V_i even once, but the result of my implementation is that every f_i() ends up calling F(V_N)
You are auto-capturing i by reference in your loop, but it's only a binding. The value is not actually used until after the loop, when calling the lambda. At that point, each call takes the captured "reference to i" (which is actually undefined behavior, given that i is no longer in scope), dereferences it and stores the value in V. You know the rest.
What is strange is that you are insisting on using references to integer values. It's likely the compiler is doing its best to inline these and just use plain copies, but you should consider that when you have a reference, you can often expect additional instructions to be generated to dereference that to a value. For primitive types, just copy.
Oh, and definitely capture i by value!!! As a matter of style, I prefer to be explicit about my captures:
function<long ()> funky = [i]() -> long {
long V = i;
return add(V, V*V, 2L);
};
I'm trying to write a generic utility function for a class that applies a function to each element of a vector with the only input argument being the value of that element. The idea being that I can use that to support scalar addition/multiplication as well as user-specified functions without duplicating too much code. It works fine for the user-specified functions, but I'm struggling with how the best implement it for scalar addition/multiplication.
The code below is a simplified version of what I'm playing around with. It works fine, but what I want to be able to do is have the "5" in the lambda expression be a variable passed in separately, but not necessarily passed into "apply_f". So keep apply_f only taking a vector an a function pointer. I'm aware of the captures field for lambda expressions, but I was having trouble passing a lambda function with a capture into another function. I'm also aware of something like std::bind, but couldn't get that to work either.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
void apply_f(vector<double>& vec, double (*f)(double)) {
transform(vec.begin(), vec.end(), vec.begin(), f);
}
int main() {
vector<double> x {1, 2, 3};
auto f = [](double x){ return x + 5; };
apply_f(x, f);
cout << x[0] << endl;
cout << x[1] << endl;
cout << x[2] << endl;
}
Simply take a parameter with a unique type:
template <class F>
void apply_f(vector<double>& vec, F f) {
transform(vec.begin(), vec.end(), vec.begin(), f);
}
Not only it will work, but you will get way better performance since the compiler knows the actual type being passed.
Unfortunately, lambdas are not just pointers to functions (because they can have state, for instance). You can change your code to use a std::function<double(double) instead of a double(*)(double), and this can capture a lambda (you may need to pass std::cref(f) instead of just f).
This question already has answers here:
How to use range-based for() loop with std::map?
(5 answers)
Closed 9 years ago.
The new range-based for loops really improve readability and are really easy to use. However, consider the following :
map<Foo,Bar> FooAndAssociatedBars;
for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
FooAndAssociatedBar.first.doSth();
FooAndAssociatedBar.second.doSomeOtherThing();
}
It may be a detail but I find it would have been more readable if I could have done something like :
for ( (auto& foo, auto& bar) : FooAndAssociatedBars) {
foo.doSth();
bar.doSomeOtherThing();
}
Do you know an equivalent syntax ?
EDIT:
Good news: C++17 has a proposal that adresses this problem, called structured bindings (see 1). In C++17, you should be able to write:
tuple<T1,T2,T3> f(/*...*/) {
/*...*/
return {a,b,c};
}
auto [x,y,z] = f(); // x has type T1, y has type T2, z has type T3
which solves this readability problem
There is no such thing as you want. The closest is to declare variables inside the loop:
for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
auto& foo = FooAndAssociatedBar.first;
auto& bar = FooAndAssociatedBar.second;
// ...
}
Not a good idea. Sooner or later, you would want the same for a std::tuple, and compiler should be able to use std::get<> on the tuple automatically. In my opinion your approach is pleasing you at the moment only, and you would find problems with this approach (assume it is implemented that way).
Standard committee has designed range-based for-loop with deep consideration. It is way better than foreach loop in other languages, and it is way shorter. Couple it with auto& and you are done!
And of course, you always have the possibility to use lambdas.
std::map<int, const char*> m { { 4, "hello" }, { 11, "c++" } };
convenient_for_each(m, [](int a, const char* b) {
std::cout << b << a << std::endl;
});
convenient_for_each(m, [](std::pair<int, const char> p) {
std::cout << p.first << p.second << std::endl;
});
Or wrapped as macro (not recommended)
FOREACH((int a, const char* b), m, std::cout << a << b << std::endl);
FOREACH((std::pair<int, const char*> p), m, std::cout << p.first << p.second << std::endl);
(Hackish sample implementation at LWS)
Auto won't work though, I'm still waiting for polymorphic lambdas. My approach is theoretically able to handle tuples as well.
How to translate properly the following Java code to C++?
Vector v;
v = getLargeVector();
...
Vector getLargeVector() {
Vector v2 = new Vector();
// fill v2
return v2;
}
So here v is a reference. The function creates a new Vector object and returns a reference to it. Nice and clean.
However, let's see the following C++ mirror-translation:
vector<int> v;
v = getLargeVector();
...
vector<int> getLargeVector() {
vector<int> v2;
// fill v2
return v2;
}
Now v is a vector object, and if I understand correctly, v = getLargeVector() will copy all the elements from the vector returned by the function to v, which can be expensive. Furthermore, v2 is created on the stack and returning it will result in another copy (but as I know modern compilers can optimize it out).
Currently this is what I do:
vector<int> v;
getLargeVector(v);
...
void getLargeVector(vector<int>& vec) {
// fill vec
}
But I don't find it an elegant solution.
So my question is: what is the best practice to do it (by avoiding unnecessary copy operations)? If possible, I'd like to avoid normal pointers. I've never used smart pointers so far, I don't know if they could help here.
Most C++ compilers implement return value optimization which means you can efficiently return a class from a function without the overhead of copying all the objects.
I would also recommend that you write:
vector<int> v(getLargeVector());
So that you copy construct the object instead of default construct and then operator assign to it.
void getLargeVector(vector<int>& vec) {
// fill the vector
}
Is a better approach for now. With c++0x , the problem with the first approach would go by making use of move operations instead copy operations.
RVO can be relied upon to make this code simple to write, but relying RVO can also bite you. RVO is a compiler-dependent feature, but more importantly an RVO-capable compiler can disable RVO depending on the code itself. For example, if you were to write:
MyBigObject Gimme(bool condition)
{
if( condition )
return MyBigObject( oneSetOfValues );
else
return MyBigObject( anotherSetOfValues );
}
...then even an RVO-capable compiler won't be able to optimize here. There are many other conditions under which the compiler won't be able to optimize, and so by my reckoning any code that by design relies on RVO for performance or functionality smells.
If you buy in to the idea that one function should have one job (I only sorta do), then your dilema as to how to return a populated vector becomes much simpler when you realize that your code is broken at the design level. Your function really does two jobs: it instantiates the vector, then it fills it in. Even with all this pedantary aside, however, a more generic & reliable solution exists than to rely on RVO. Simply write a function that populates an arbitrary vector. For example:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename Iter> Iter PopulateVector(Iter it, size_t howMany)
{
for( size_t n = 0; n < howMany; ++n )
{
*(it++) = n;
}
return it;
}
int main()
{
vector<int> ints;
PopulateVector(back_inserter(ints), 42);
cout << "The vector has " << ints.size() << " elements" << endl << "and they are..." << endl;
copy(ints.begin(), ints.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
static const size_t numOtherInts = 42;
int otherInts[numOtherInts] = {0};
PopulateVector(&otherInts[0], numOtherInts);
cout << "The other vector has " << numOtherInts << " elements" << endl << "and they are..." << endl;
copy(&otherInts[0], &otherInts[numOtherInts], ostream_iterator<int>(cout, " "));
return 0;
}
Why would you like to avoid normal pointers? Is it because you don't want to worry about memory management, or is it because you are not familiar with pointer syntax?
If you don't want to worry about memory management, then a smart pointer is the best approach. If you are uncomfortable with pointer syntax, then use references.
You have the best solution. Pass by reference is the way to handle that situation.
Sounds like you could do this with a class... but this could be unnecessary.
#include <vector>
using std::vector;
class MySpecialArray
{
vector<int> v;
public:
MySpecialArray()
{
//fill v
}
vector<int> const * getLargeVector()
{
return &v;
}
};