Search code examples
c++setconstantsshared-ptr

Remove from a std::set<shared_ptr<T>> by shared_ptr<const T>


I have a a function, that essentially boils down to this (the part that I'm struggling with, ignoring the stuff that is actually happening)

class CellSorter
{
public:
    bool operator()( std::shared_ptr<const Cell> a,
                     std::shared_ptr<const Cell> b ) const
    {
        return ( ( a->GetY() < b->GetY() ) ||
                 ( a->GetY() == b->GetY() &&
                   a->GetX() < b->GetX() ) );
    }
};
typedef std::set<std::shared_ptr<Cell>, CellSorter> Container;
MyClass::Container MyClass::DoSomething( std::shared_ptr<const Cell> c )
{
    MyClass::Container N;
    // assume that this code works to copy some stuff to N, blah blah blah
    std::remove_copy_if( _grid.begin(), _grid.end(),
                         std::inserter( N, N.begin() ),
                         std::not1( CellIsNeighbor( c->GetX(), c->GetY() ) ) );
    N.erase( c ); // ERROR
    return N;
};

The problem is, gcc gives me an error:

/usr/include/c++/4.4/bits/shared_ptr.h:651: error: invalid conversion from ‘const Cell*’ to ‘Cell*’

I thought that this should not be casting the object "c" from shared_ptr<const Cell> to shared_ptr<Cell>, but somehow it is. I want c to point to a const Cell because there is no need to modify it. And the CellSorter shouldn't have a problem with const.

Any ideas as to why I can't do this or how to fix it?


Solution

  • It's because the shared_ptr in Container has type std::shared_ptr<Cell>. You are passing a std::shared_ptr<const Cell> to the erase() method. Different types. You can fix it by removing the const qualifier.

    Apparently you can also use std::const_pointer_cast in this situation.

    http://msdn.microsoft.com/en-us/library/bb982336.aspx