1

I'm aware of declaring and initializing two different variables in a for loop with a std::pair or an anonymous struct type, but these do not work for my purposes.

Let's say I have the following class definition

class Object {
    private:
        int i;
    public:
        Object(int i) : i(i) { }
        // everything else deleted
        Object() = delete;
        Object(const Object &) = delete;
        Object(Object &&) = delete;
        Object & operator=(const Object &) = delete;
        Object & operator=(Object &&) = delete;
};

Is there any way I can initialize an Object and an int in the for loop line. I don't want to add an extra block around the for loop or anything like that. I am okay with std::tuple, std::pair, anonymous structs, whatever, just so long as it has the form

for(/* creates Object and int*/ ; /*whatever*/; /*whatever*/) { /* ... */}

or (if the syntax existed)

for( Object o(69), int i = 0; i < 10; ++i) { /* ... */ }

What I do not want is an extra named class definition. I have come up with this already:

for(class Container : private Object {
            public:
                int value;
                Container(int i) : Object(i), value(0) { }
                } container(69); /* ... */ ;
        container.value < 10;
        ++container.value) { /* ... */}

But the class name Container then becomes visible inside of the for loop, which I am trying to avoid.

My actual use of this is a std::lock_guard<std::mutex> and a bool, so that the mutex is released after exiting the loop.

Community
  • 1
  • 1
Ryan Haining
  • 30,835
  • 10
  • 95
  • 145
  • No need to delete the move functions if you already delete the copying versions. – Kerrek SB Sep 10 '13 at 18:08
  • This question is super vague. Why not just `for(/*whatever*/) {int i; Object o; /*code*/}`? What problem are you trying to solve? – Mooing Duck Sep 10 '13 at 18:14
  • @MooingDuck yes, perhaps too vague, sorry about that. Doing the above would create a new `i` and `o` on each iteration, as opposed to the normal for loop variable declarations. – Ryan Haining Sep 10 '13 at 18:16
  • @MooingDuck: The `int i; Object o;` should be put *outside* of the for-loop. – kennytm Sep 10 '13 at 18:29

2 Answers2

6

You could use piecewise construction to invoke the constructors:

for (std::pair<Object, int> x (std::piecewise_construct,
                               std::make_tuple(69),
                               std::make_tuple(0));
     x.second < 10; x.second ++) {

    std::cout << x.first.i << "/" << x.second << std::endl;
    x.first.i += 4;
}

Unfortunately this does not generalize to tuples. There is no piecewise constructor for std::tuple.


Not sure why you disregard it, but I find the "pair" solution is very ugly compared to the more straight-forward implementation

{
    Object o (69);
    for (int i = 0; i < 10; ++ i) {
        std::cout << o.i << "/" << i;
        o.i += i;
    }
}
kennytm
  • 469,458
  • 94
  • 1,022
  • 977
1

Yes, with optional:

#include <utlility>

std::optional<Object> o;

for ( ; ; )
{
    o.emplace(12);
}

(This is available in C++14, but also from <boost/optional.hpp>.)

Kerrek SB
  • 428,875
  • 83
  • 813
  • 1,025