0

edit: As mentioned by @HolyBlackCat "If you need it to retain it's [a variable's] value between iterations, it has to stay outside." This is of course true of even primitive types, eg. int. So this question is actually just noise, sorry.

I'm trying to get my head around how to be consistent when declaring objects, the "declare variable inside or outside loop?" issue for variables that are only used inside a loop. See eg. Declaring variables inside loops, good practice or bad practice?.

Consider the below examples. Let V be an object which has a default constructor.

                                  // Example 1
std::vector<int> V;               // Works as intended
for (int i=0; i<2; i++) {         // ...but V should be declared inside loop(?)
    V.push_back(i);
    // V used only inside loop
}                                 
                                  // Example 2 
for (int i=0; i<2; i++) {         // OK Syntax, Wrong Semantics
    std::vector<int> V;           // V is "created" anew in each loop-step
    V.push_back(i);
    // V used only inside loop         
}
                                  // Example 3
for (int i=0; i<2; i++) {         // Syntax Error, other syntax possible?
    std::vector<int> V.push_back(i);
    // V used only inside loop 
}

Example 1: Defines the approximate semantics im looking for - besides that V is local to the loop and I would prefer to define V inside the loop.

Example 2: Defines V inside the loop but also creates it anew in each loop-step, this is NOT the desired semantics.

Example 3: "Nice try" exploration of syntax - Im trying to declare and "immediately use" the object V. This is illegal syntax.

If, at the end of the day, many types of objects are most elegantly declared outside the loop (as it would seem to be the case with V in the example; otherwise, if declared inside the loop, the declaration would have to be somehow "guarded") then i might just lean to declaring everything outside the loop, just before the loop, instead of inside the loop...

Please give me advice on this issue, how to get the semantics of Example 1 but with V declared inside the loop (if possible).

mrchance
  • 1,133
  • 8
  • 24
  • 2
    Yes, another syntax is possible: `for (int i=0; i<2; i++) { std::vector().push_back(i); }` Can't name it `V` though, the unnamed vector only lives until the `;` of the statement. – Eljay Aug 04 '20 at 16:29
  • @Eljay great!! this was what i was looking for. please post as answer and i will acknowledge it. thanks – mrchance Aug 04 '20 at 16:31
  • 2
    But what does this *achieve*? It's very unclear what you want to actually happen. – cigien Aug 04 '20 at 16:33
  • @Eljay, snap then its no good... anyway that was the semantics i was looking for – mrchance Aug 04 '20 at 16:33
  • Well, for academic learning purposes, it's good to know that syntax. But there isn't too many use cases for it, which is why a lot of us are curious as to what you are trying to do with it. – Eljay Aug 04 '20 at 16:33
  • @cigien, im trying to get my head around how to be consistent when declaring objects, the inside/outside loop issue for loop-local variables. if at the end of the day, many types of objects must be declared outside the loop (as it seems is the case with V in the example) then i might lean to just declaring everything outside, just before the loop, instead of inside... – mrchance Aug 04 '20 at 16:36
  • By any chance are you looking to make `V` static? You still won't be able to use `V` outside the loop though. – cigien Aug 04 '20 at 16:36
  • 3
    Don't stress out about it. Get into the habit of declaring things as local as possible, and you'll be fine. – cigien Aug 04 '20 at 16:37
  • 1
    The snippet marked "OK" is the right way to do it in C++. The part marked "does NOT work" won't work in C++, as indicated, and the alternatives (like using a lambda) won't satisfy the intent. Use the "OK" way, it's okay. – Eljay Aug 04 '20 at 16:57
  • 1
    (The "does not work" way is not relevant to your motivating questions. Bit of a red herring. Some of us — including myself — fixated on it. Sorry about that.) – Eljay Aug 04 '20 at 17:04
  • @Eljay, thx, you are absolutely right, i rewrote the question entirely. I originally put "Edited" into the post, but another person adviced me not to since edits are available in the editing history.... – mrchance Aug 04 '20 at 17:27

2 Answers2

1

Yes, you can do this:

std::vector<int> V{i}; 

which initializes the vector V with the value i when it's declared.


On the other hand, neither of your loops are actually doing anything useful. You are redeclaring V inside the loop every time, so previous push_backs are not visible. Also, V is not usable outside the scope of the for loop.

It seems that what you are trying to do is fill a vector with counting numbers. The easy way to do that is:

std::vector<int> V(2);
std::iota(V.begin(), V.end(), 0);
cigien
  • 57,834
  • 11
  • 73
  • 112
  • but that does not grow V as in the example? – mrchance Aug 04 '20 at 16:20
  • 3
    Your example doesn't grow `V` either. You are redeclaring `V` inside the loop every time. – cigien Aug 04 '20 at 16:21
  • Another option would be to use `std::vector V(1, i);`. But the only advantage I can think of for that is that it would work with pre-C++11 compilers. – Fred Larson Aug 04 '20 at 16:21
  • thanks all, but whats up with the recommendation of declaring a loop-local object inside the loop? how would i do that in this case? – mrchance Aug 04 '20 at 16:25
  • I've never heard that recommendation before. And as I mentioned in the answer, it's not going to do anything useful if it's loop-local. – cigien Aug 04 '20 at 16:26
  • @cigien, regarding defining inside/outside loops https://stackoverflow.com/questions/7959573/declaring-variables-inside-loops-good-practice-or-bad-practice – mrchance Aug 04 '20 at 16:28
  • In that question, the variable is being used inside the loop. In your code, `V` is not being used inside the loop. If you want to use `V` outside the loop, it *must* be declared outside the loop. – cigien Aug 04 '20 at 16:30
  • 1
    @newbie The general rule is to declare a variable as late as possible, yes. But if you need it outside of the loop, then it's not really possible to declare it inside. – HolyBlackCat Aug 04 '20 at 17:16
  • @HolyBlackCat in the example V is only used inside the loop, thats the general case im interested in, thx – mrchance Aug 04 '20 at 17:25
  • 1
    @newbie If you need it to retain it's value between iterations, it has to stay outside. – HolyBlackCat Aug 04 '20 at 17:51
  • @cigien I suggest `std::vector V = {i};` instead of `std::vector V{i};`. Without `=`, the behavior changes depending on the element type (1 element `i`, or `i` elements), and with `=` it's always a single element (or a error if `i` is not convertible to an element). – HolyBlackCat Aug 04 '20 at 17:52
  • @HolyBlackCat ok i get it + facepalm, this is actually the case for _any_ kind of object, even primitive types, int, char... just plain wrong thinking here on my part. maybe id better delete this question? – mrchance Aug 04 '20 at 18:07
  • You can't delete it at this point (after getting an upvoted answer, or any answer at all, I don't remember) anyway. :P – HolyBlackCat Aug 04 '20 at 18:11
0

You're trying to declare a new vector every time and directly using the push_back on declaration, that's impossible, i.e. the statement:

is it possible to declare and immediately use the object V, in the very same declarative statement

isn't correct.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34