BlazePascal
BlazePascal

Reputation: 401

Holding a reference to a unique_ptr while looping

I want to hold a reference to a unique_ptr while using a loop, so that after I get out of the loop I still hold the reference. I know that I can't create a new copy of the unique_ptr (obviously), so what I want to do is something like:

const unique_ptr<Object>& ref;
for(auto& s : stuff) {
    if(condition) {
         ref = std::move(s);
    }
}

I realize this will never work because ref must be initialized at declaration if it is to be a const, but in that same motion I can't hold a reference to a unique_ptr unless it is a const unique_ptr& type if I am not mistaken. What I ended up doing is:

Object* ref = nullptr;
for(auto& s : stuff) {
    if(condition) {
         ref = s.get();
    }
}

Is that a correct solution or should I just consider using shared_ptr for this job?

Upvotes: 3

Views: 519

Answers (3)

Galik
Galik

Reputation: 48625

I know this may seem counter-intuitive but, given that your object is already managed by a std::unique_ptr, and therefore its destruction is guaranteed, I see nothing wrong with using the raw pointer:

Object* o = nullptr;

for(auto& s : stuff) {
    if(condition) {
         o = s.get();
    }
}

if(o) {
    // use o->stuff() here
}

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

You shouldn't do any of that! You shouldn't even use a loop [explicitly]! Instead, just find the position and go from there:

auto it = std::find_if(stuff.begin, stuff.end(),
     [](std::unique_ptr<Object> const& s){ return condition(s); });
if (it != stuff.end()) {
    // get your unique_ptr as appropriate from *it
}
else {
    // deal with the fact that nothing was found
}

Upvotes: 6

Functional style to the rescue!

const auto &ref = *std::find_if(stuff.begin(), stuff.end(), [=](const std::unique_ptr<Object> &p) {
    return <condition>;
});

Alternatively, move assignment:

std::unique_ptr<Object> ref;
for (auto &&s : stuff) {
    if (condition) {
        ref = std::move(s);
        break;
    }
}

Upvotes: 6

Related Questions