Форум программистов, компьютерный форум CyberForum.ru

Метод remove_if STL - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 20:31     Метод remove_if STL #1
Всем привет!

Не могу понять почему вылезает ошибка при использовании remove_if для list.

ошибка

C++
1
Error   1   error C3867: 'CableTV::HelpDeleteChannels': function call missing argument list; use '&CableTV::HelpDeleteChannels' to create a pointer to member   c:\documents and settings\304-03\мои документы\visual studio 2010\projects\examwinapi\examwinapi\examwinapi.cpp 895
Код

l
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
list < ListChannel > :: iterator iteratorchannel;
iteratorchannel = remove_if( listchannel.begin(),listchannel.end(),HelpDeleteChannels);
 
bool CableTV :: HelpDeleteChannels( ListChannel &channel)
{
    int position;
    position = SendMessage( hList1,LB_GETCURSEL,0,0 );
    wstring numberpaket;
    SendMessage( hList1,LB_GETTEXT,position,( LPARAM )numberpaket.c_str( ) );// получение номера пакета
    position =_wtoi( numberpaket.c_str(  ) );
    return true;
 
}
Заранее спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.08.2012, 20:31     Метод remove_if STL
Посмотрите здесь:

C++ STL и функция remove_if
метод erase для list(STL) C++
C++ Метод STL size и инициализация списка
C++ stl::vector, метод pop_back()
Remove_if - при передаче функции класса выдает ошибки C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,568
Записей в блоге: 17
22.08.2012, 20:51     Метод remove_if STL #2
Потому что передавать надо функтур, а не метод класса ( причем всегда возвращающий true )

http://www.cplusplus.com/reference/algorithm/remove_if/
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:00  [ТС]     Метод remove_if STL #3
Цитата Сообщение от Avazart Посмотреть сообщение
Потому передавать надо функтур, а не метод класса...
C++
1
This can either be a pointer to a function or an object whose class overloads operator().
Надо передавать указатель на функцию или объект, это я понял. Но я применяю list в WinApi, где работаю без объектов.
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,568
Записей в блоге: 17
22.08.2012, 21:02     Метод remove_if STL #4
Но я применяю list в WinApi, где работаю без объектов.
не понимаю как это влияет на суть проблемы....
Пaтрик
 Аватар для Пaтрик
394 / 387 / 38
Регистрация: 21.01.2012
Сообщений: 972
Завершенные тесты: 1
22.08.2012, 21:05     Метод remove_if STL #5
Holsteng, итераторы в Вашем коде разве не объекты? Передайте указатель на функцию.
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:08  [ТС]     Метод remove_if STL #6
Avazart, я Вас понял, что надо создать функцию, не метод класса и записать ее в метод remove_if, я так сделал, но все - равно вылетает ошибка, которую я писал
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,568
Записей в блоге: 17
22.08.2012, 21:10     Метод remove_if STL #7
C++
1
2
3
4
5
6
7
8
bool HelpDeleteChannels(const ListChannel &channel)
{
  // ... 
    return true;
}
//-------------------------------------------------------------------------------------
list < ListChannel > :: iterator iteratorchannel;
iteratorchannel = remove_if( listchannel.begin(),listchannel.end(),HelpDeleteChannels);
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:11  [ТС]     Метод remove_if STL #8
Пaтрик, не пойму как это сделать, ведь я должен указать только имя функции
Mиxaил
 Аватар для Mиxaил
530 / 435 / 37
Регистрация: 10.12.2009
Сообщений: 1,857
22.08.2012, 21:11     Метод remove_if STL #9
Нужно что-то типа такого:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <algorithm>
#include <list>
 
class functor
{
   public:
      bool operator()( const int n ) const
      {
         return n % 2 == 0;
      }
};
 
int main()
{
   std::list < int > lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   std::remove_if( std::begin( lst ), std::end( lst ), functor() );
   for( const auto &_x : lst )
      std::cout << _x << std::endl;
   return 0;
}
Ссылка для проверки: http://liveworkspace.org/code/ff81b8...1cd4ae51313ce9

Добавлено через 34 секунды
или свою лямбду писать...
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:14  [ТС]     Метод remove_if STL #10
Цитата Сообщение от Avazart Посмотреть сообщение
list < ListChannel > :: iterator iteratorchannel;
iteratorchannel = remove_if( listchannel.begin(),listchannel.end(),HelpDeleteChannels);
Этот код у меня находиться в методе, а убрать нельзя
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,568
Записей в блоге: 17
22.08.2012, 21:16     Метод remove_if STL #11
Бросайте компилятор, код , бегите читать книги и не парьте нам мозг
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
22.08.2012, 21:30     Метод remove_if STL #12
много вариантов, можно например в таком духе

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
 
class A {
public:
  bool predicat_delete (const int value) {
    return value > 3;
  }
};
 
int main () {
  A a;
 
  std::vector<int> v;
  v.push_back (4);
  v.push_back (3);
  v.push_back (2);
  v.push_back (5);
  v.erase (std::remove_if(v.begin(),
                          v.end(),
                          std::bind1st(std::mem_fun(&A::predicat_delete), &a)), v.end());
  std::copy (v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
правда bind* не переваривает ссылок, что исправлено в std::bind в с++11

Добавлено через 10 минут
если оно уже встроено в другой класс, то это тоже можно ообойти

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
 
class A {
public:
  bool predicat_delete (const int& value) { 
    return value > 3;
  } 
};
 
namespace {
  typedef bool (A::*checker)(const int&);
  struct DeleteFunctor {
    DeleteFunctor (A& _a, checker _check) : a(_a), check(_check) {}
    bool operator ()(const int& value) { return (a.*check)(value); }
  private:
    A& a;
    checker check;
  };
}
 
int main () {
  A a;
 
  std::vector<int> v;
  v.push_back (4);
  v.push_back (3);
  v.push_back (2);
  v.push_back (5);
 
  v.erase (std::remove_if(v.begin(), 
                          v.end(), 
                          DeleteFunctor(a, &A::predicat_delete)), v.end());
  std::copy (v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:31  [ТС]     Метод remove_if STL #13
Написал преподу, говорит необходимо сделать метод класса, который выступает в качестве предиката статическим, попробовал, все нормально, однако проблема в другом. В предикат, ведь можно передать только один параметр, а мне необходимо получить с поля ввода число, а вызвать нестатическую функцию из статического метода нельзя.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
22.08.2012, 21:33     Метод remove_if STL #14
Holsteng, в статическую функцию можно передать указатель на объект и через него дергать методы
еще учти, что remove_if не удаляет элементы
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:40  [ТС]     Метод remove_if STL #15
Спасибо! Но проблема в том что мне необходимо в предикате получить число из поля ввода, там же this не доступен, а в предикат более одного параметра нельзя передавать. Ребята проблема возникла из - за чего. Я удалял из list элементы в цикле и когда элемент оказывался последним вылетала ошибка, что невозможно инкремировать итератор.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
22.08.2012, 22:11     Метод remove_if STL #16
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
bool CableTV :: HelpDeleteChannels( ListChannel &channel)
{
    int position;
    position = SendMessage( hList1,LB_GETCURSEL,0,0 );
    wstring numberpaket;
    SendMessage( hList1,LB_GETTEXT,position,( LPARAM )numberpaket.c_str( ) );// получение номера пакета
    position =_wtoi( numberpaket.c_str(  ) );
    return true;
 
}
 
class Functor {
public: 
  Functor (CableTV& _cable_tv) : cable_tv(_cable_tv) {}
  bool operator () (ListChannel &channel) {
     return cable_tv.HelpDeleteChannels(channel);
  }
};
 
...
 
CableTV cable_tv;
 
listchannel.erase (std::remove_if(listchannel.begin(),
                        listchannel.end(),
                        Functor(cable_tv), listchannel.end());
такой псевдокод
вы точно правильно понимаете для чего нужен remove_if?
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
23.08.2012, 13:26  [ТС]     Метод remove_if STL #17
Всем спасибо, решил задачу проще. В цикле где применяю проверку, а потом удаление элемента списка с помощью erase поставил проверку на позицию итератора и если конец списка - выход из цикла.
Цитата Сообщение от alex_x_x Посмотреть сообщение
listchannel.erase (std::remove_if(listchannel.begin(), listchannel.end(), Functor(cable_tv), listchannel.end());
Мне не совсем понятно, зачем нужен четвертый параметр
C++
1
listchannel.end()
Я читал, что remove_if можно применять с двумя итераторами, но никогда не использовал, подскажите, пжлста. Спасибо
Andsteadur
152 / 136 / 3
Регистрация: 23.05.2009
Сообщений: 275
23.08.2012, 14:24     Метод remove_if STL #18
тут потерялась одна скобка
C++
1
listchannel.erase (std::remove_if(listchannel.begin(), listchannel.end(), Functor(cable_tv)), listchannel.end());
remove_if "переносит" все подходящие под условие элементы в конец контейнера, не удаляя их, а возвращает итератор на первый такой элемент. соответственно начиная с позиции, на которую ссылается итератор и до конца находятся тех элементы, которые нужно удалить. Соответственно мы вызываем erase, чтобы действительно удалить эти элементы.

т.е. предположим есть контейнер со следующими данными

C++
1
v = { 0, 1, 3, 6, 3, 2, 11, 3, 5, 6}
после вызова remove_if для удаления всех элементов 3 контейнер будет таким

C++
1
2
3
4
v = {0, 1, 6, 2, 11, 5, 6, 3, 3, 3}
                           ^
                           |
                     remove_if вернет итератор на этот элемент
Соответственно, нам нужно вызвать erase начиная с этого итератора и заканчивая концом вектора.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.08.2012, 14:31     Метод remove_if STL
Еще ссылки по теме:

C++ Remove_if для std::list
Метод ближайшего соседа через STL Algorithm C++
C++ СЛАУ. Метод обратной матрицы, метод Гаусса, метод Крамера, метод Зейделя

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Holsteng
 Аватар для Holsteng
47 / 10 / 3
Регистрация: 26.03.2012
Сообщений: 246
23.08.2012, 14:31  [ТС]     Метод remove_if STL #19
Спасибо, теперь я понял
Yandex
Объявления
23.08.2012, 14:31     Метод remove_if STL
Ответ Создать тему
Опции темы

Текущее время: 23:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru