Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C++ std::equal on a container of shared_ptr

I have a container of std::shared_ptr. I want to compare two containers using std::equal. The class A has operator== defined. I want equal to compare if each element is equivalent using its operator==, not the one defined in shared_ptr.

Do I need to make a function or function object to pass to equal? Or is there something built-in that would be simpler (like something defined in <functional>)?

like image 825
Matt Avatar asked Mar 31 '11 18:03

Matt


People also ask

Can shared_ptr be Nullptr?

A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .

What is the purpose of the shared_ptr <> template?

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.

What is Sharedptr?

The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.

What happens when you move a shared_ptr?

By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).


2 Answers

You will need a function or a function object or a lambda expression (since you're able to use std::shared_ptr, you have some part of C++0x already enabled).

There is nothing in <functional> to help you, but there is something in boost: the indirect iterator

#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <boost/iterator/indirect_iterator.hpp>
int main()
{
        std::vector<std::shared_ptr<int>> v1;
        std::vector<std::shared_ptr<int>> v2;
        v1.emplace_back( new int(1) );
        v2.emplace_back( new int(1) );

        bool result =
            std::equal( boost::make_indirect_iterator(v1.begin()),
                        boost::make_indirect_iterator(v1.end()),
                        boost::make_indirect_iterator(v2.begin()));
        std::cout << std::boolalpha << result << '\n';
}
like image 76
Cubbi Avatar answered Sep 29 '22 19:09

Cubbi


You could do something like the following, assuming you have a compiler that supports lambdas and that no items are ever null:

bool CompareA(const vector<shared_ptr<A>>& first, 
              const vector<shared_ptr<A>>& second) {

   return equal(first.begin(), first.end(), second.begin(),
              [](const shared_ptr<A>& item1, const shared_ptr<A>& item2) -> bool{
                   return (*item1 == *item2);
               });
}
like image 29
bsruth Avatar answered Sep 29 '22 18:09

bsruth