Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare and assign between std::vector<T> and std::vector<std::reference_wrapper<T>>?

Here are two different type of std::vector, as an example:

std::vector<std::reference_wrapper<MyClass>> rv;
std::vector<MyClass> v;

A possible way to assign between them is:

for (const auto& mc : rv) {
    v.push_back(mc.get());
}

It works. But ugly and maybe slow. The same as comparison:

bool is_same(std::vector<MyClass>& v, std::vector<std::reference_wrapper<MyClass>>& rv) {
    if (v.size()!=rv.size()) {
        return false;
    }
    for (size_t i = 0; i < v.size(); v++) {
        if (v[i]!=rv[i].get()) {
            return false;
        }
    }
    return true;
}

Is there any better way to do this work? Smart and quick.

like image 229
Ringo_D Avatar asked Apr 15 '26 01:04

Ringo_D


1 Answers

Since std::reference_wrapper is implicitly convertible to a reference to the type it holds, you can assign one to MyClass. So a better way to initialize one with the other is the appropriate vector constructor:

std::vector<MyClass> v(begin(rv), end(rv));

Or, if you really need to assign:

v.assign(begin(rv), end(rv));

You can do the comparison by applying the std::mismatch algorithm, again thanks to the implicit conversion provided by std::reference_wrapper:

bool is_same(std::vector<MyClass> const& v, std::vector<std::reference_wrapper<MyClass>> const& rv) {
  return v.size() == rv.size() &&
         end(v) == std::mismatch(begin(v), end(v), begin(rv), end(rv)).first;
}

As a general rule of thumb, it's always good to consult the standard algorithm library before writing loops yourself. It makes your own code more readable by giving verbs and nouns to computation steps. And has the benefit of allowing for any optimizations the standard library can offer.


As cppleaner pointed out, I should have consulted the library more closely myself. is_same can be implemented even more easily by a simple call to std::equal

return std::equal(begin(v), end(v), begin(rv), end(rv));
like image 125
StoryTeller - Unslander Monica Avatar answered Apr 17 '26 16:04

StoryTeller - Unslander Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!