Я запустил ваш пример, затем добавил несколько утверждений, которые, как я думал, должны содержаться в del()
:
assert(!(v_param < v_ptr));
assert(!(v_ptr < v_param));
Одна из них не удалась!
Я копался в реализации operator<
для boost::shared_ptr
и нашел что-то странное: он сравнивает счетчики ссылок, а не внутренние указатели!Небольшое копание нашло сообщение в списке рассылки об этой проблеме с некоторыми полезными ссылками на два документа C ++: N1590, которое объясняет, почему люди думают, что это хорошая идея, и N2637, которое объясняет, почему это не так.
Похоже, что люди из Boost еще не приняли рекомендацию N2637, а C ++ 11.Поэтому я снова построил ваш тест, используя C ++ 11 (g++ -std=c++0x
), удалив using namespace boost;
, чтобы использовать std::shared_ptr
.Это привело к появлению ужасного сообщения об ошибке на основе шаблона, которое было решено путем добавления этого сверху (легко выводится из boost/smart_ptr/shared_ptr.hpp
):
template<class T> inline T * get_pointer(std::shared_ptr<T> const & p)
{
return p.get();
}
И это работает!
Если вы можетене используйте C ++ 11, просто реализуйте свой собственный компаратор для вашего набора, который разумно сравнивает указатели:
template <typename T>
struct SmartComparator
{
bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
return lhs.get() < rhs.get();
}
};
Тогда это будет работать:
set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;