boost :: ptr_vector и find_if - PullRequest
       35

boost :: ptr_vector и find_if

0 голосов
/ 24 июня 2010

У меня есть класс:

//header file
class CMDatabase
{
    class Try;
    typedef boost::shared_ptr<Try> TryPtr;
    typedef boost::ptr_vector<Try> TryVector;
    typedef TryVector::iterator TryVectorIterator;

    class Try
    {
        public:
            virtual ~Try();
            virtual bool equal(CMDatabase::TryPtr mySd) = 0;
    };
};

//.cpp file

class TryImpl : public CMDatabase::Try
{
    bool equal(CMDatabase::TryPtr mySd)
    {
        //boost::shared_ptr<ServiceDataImpl> ServiceDataImplPtr;
        //const ServiceDataImplPtr pOtherData = dynamic_cast<const ServiceDataImplPtr>(mySd);

        //ServiceDataImpl *pOtherData = dynamic_cast<ServiceDataImpl *>(mySd.get());
        return true;
    }
};

//Another .cpp file

void UpdateClass::TryFind()
{
    CMDatabase::TryVector defaultTry;
    CMDatabase::TryVector updateTry;

//Code for filling two vectors here....

    for(CMDatabase::TryVectorIterator i = defaultTry.begin(); i != defaultTry.end(); ++i)
    {
       CMDatabase::TryVectorIterator it = find_if(updateTry.begin(), updateTry.end(),bind1st(mem_fun(&CMDatabase::Try::equal), *i));

    }
}

Когда я компилирую это, я получаю ошибку:

Ошибка 1 ошибка C2440: «инициализация»:
не может преобразовать из'const CMDatabase :: Try' to 'CMDatabase :: Try
*' c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ functions 296

Может кто-нибудь сказать мне, что сказать?что я делаю не так и как это исправить.

Ответы [ 3 ]

1 голос
/ 24 июня 2010

Проблема заключается в том, что ваш equal метод не квалифицирован const.

class Try
{
public:
  virtual ~Try();
  virtual bool equal(CMDatabase::TryPtr const& mySd) const = 0;
};

bool TryImpl::equal(CMDatabase::TryPtr const& mySd) const { return true; }

Примечание:

  • const, добавленный в метод, в противном случае оннельзя использовать на const объектах
  • const, добавленных к указателю: копирование shared_ptr стоит, потому что это требует увеличения общего счетчика и последующего уменьшения его.

РЕДАКТИРОВАТЬ :

Напоминание для неосторожных: библиотека контейнера указателей была разработана таким образом, чтобы интерфейс был максимально прост в использовании, и одним из преимуществ является то, что вы надеваетене нужно удваивать разыменование.Это компилирует:

 boost::ptr_vector<int> vec;
 vec.push_back(new int(3));

 int& i = *vec.begin();

Таким образом, ваш функтор должен брать ссылку, а не указатель:)

1 голос
/ 24 июня 2010

Просто для полноты, следующее утверждение неверно!Спасибо Мэтью М. за то, что он указал на мою ошибку!

При разыменовании итератора контейнера указателя буста вы получите чистый указатель на элемент.Таким образом, вы можете попытаться разыменовать чистый указатель, полученный через итератор:

CMDatabase::TryVectorIterator it =
  find_if(updateTry.begin(), updateTry.end(), bind1st(mem_fun(&CMDatabase::Try::equal), **i));

Там, где следующее по-прежнему верно;)

Или вы можетеиспользуйте operator[] реализацию boost::ptr_vector, которая будет возвращать ссылку на элемент:

for (std::size_t i = 0, l = ; defaultTry.size(); ++i) {
  CMDatabase::TryVectorIterator it = std::find_if(
    updateTry.begin(),
    updateTry.end(),
    std::bind1st(std::mem_fun(&CMDatabase::Try::equal), defaultTry[i])
  );
}

Надеюсь, это поможет.

0 голосов
/ 24 июня 2010

Извините, но по какой-то причине я не смог добавить комментарий к предыдущему сообщению, поэтому пишу его как ответ.

Я попробовал оба метода.Первый дает недопустимое косвенное указание.

А для второго он дает ту же ошибку: в подробном выводе детали выглядят следующим образом:

c: \ program files \ microsoft visual studio9.0 \ vc \ include \ functions (296): ошибка C2440: «инициализация»: невозможно преобразовать из «const CMDatabase :: Try» в «CMDatabase :: Try *» Нет доступного оператора преобразования, который может выполнить это преобразование,или оператор нельзя назвать c: \ fta_chk \ tools \ channel_editor \ ivodb \ channellistupdate.cpp (103): см. ссылку на создание экземпляра шаблона функции 'std :: binder1st <_Fn2> std :: bind1st, CMDatabase :: Try> (const_Fn2 &, const _Ty &) 'компилируется с помощью [_Fn2 = std :: mem_fun1_t, _Result = bool, _Ty = CMDatabase :: Try, _Arg = CMDatabase :: TryPtr]

...