Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a container of std::shared_ptr<Widget> objects?

class Widget;

std::vector< std::shared_ptr<Widget> > container

class Criterium
{
public:
    bool operator()(const Widget& left, const Widget& right)const;
};

How can I sort the container according to the Criterium, without defining another criterium like:

class CriteriumForPointers
{
public:
    bool operator()(const std::shared_ptr<Widget>& left, 
                    const std::shared_ptr<Widget>& right)const;
};
like image 857
Martin Drozdik Avatar asked Jul 06 '12 07:07

Martin Drozdik


3 Answers

You could use a lambda as an adapter:

Criterium criterium;
sort(container.begin(), container.end(),
     [&criterium] (const shared_ptr<Widget> &l, const shared_ptr<Widget> &r)
     {
         return criterium(*l.get(), *r.get());
     }
);
like image 200
Jon Avatar answered Oct 06 '22 17:10

Jon


Use indirect iterators like this:

std::sort(
  boost::make_indirect_iterator(container.begin()),
  boost::make_indirect_iterator(container.end()),
  Criterium()
);

See also: http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/indirect_iterator.html

like image 41
ltjax Avatar answered Oct 06 '22 19:10

ltjax


Maybe you could put a second overload of the operator() into your Criterium-classe, like this:

class Criterium {
  bool operator()(const Widget& left, const Widget& right)const;
  bool operator()(const std::shared_ptr<Widget>& left,
                  const std::shared_ptr<Widget>& right)const
  { return operator()( *left, *right ); }
}; 

(note: I didn't test this)

like image 1
C. Stoll Avatar answered Oct 06 '22 18:10

C. Stoll