Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/12: Рейтинг темы: голосов - 12, средняя оценка - 4.67
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
1

Метод remove_if STL

22.08.2012, 20:31. Просмотров 2198. Ответов 18
Метки нет (Все метки)

Всем привет!

Не могу понять почему вылезает ошибка при использовании 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;
 
}
Заранее спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.08.2012, 20:31
Ответы с готовыми решениями:

STL и функция remove_if
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;list&gt; #include &lt;algorithm&gt;...

STL::vector (метод resize)
Здравствуйте ,у меня возник один вопрос по поводу метода resize() ... Вот...

stl::vector, метод pop_back()
Доброго времени суток! Вот такой вопрос: я создаю объект в куче: ...

метод erase для list(STL)
Всем привет! Не могу понять в чем у меня ошибка. Применяю метод erase в...

Метод STL size и инициализация списка
Всем доброго вечера! Вот код#include &lt;fstream&gt; // для потоковых файловых...

18
Avazart
Эксперт С++
7723 / 5632 / 549
Регистрация: 10.12.2010
Сообщений: 25,402
Записей в блоге: 17
22.08.2012, 20:51 2
Потому что передавать надо функтур, а не метод класса ( причем всегда возвращающий true )

http://www.cplusplus.com/reference/algorithm/remove_if/
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:00  [ТС] 3
Цитата Сообщение от Avazart Посмотреть сообщение
Потому передавать надо функтур, а не метод класса...
C++
1
This can either be a pointer to a function or an object whose class overloads operator().
Надо передавать указатель на функцию или объект, это я понял. Но я применяю list в WinApi, где работаю без объектов.
0
Avazart
Эксперт С++
7723 / 5632 / 549
Регистрация: 10.12.2010
Сообщений: 25,402
Записей в блоге: 17
22.08.2012, 21:02 4
Но я применяю list в WinApi, где работаю без объектов.
не понимаю как это влияет на суть проблемы....
1
Пaтрик
426 / 394 / 132
Регистрация: 21.01.2012
Сообщений: 972
Завершенные тесты: 1
22.08.2012, 21:05 5
Holsteng, итераторы в Вашем коде разве не объекты? Передайте указатель на функцию.
0
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:08  [ТС] 6
Avazart, я Вас понял, что надо создать функцию, не метод класса и записать ее в метод remove_if, я так сделал, но все - равно вылетает ошибка, которую я писал
0
Avazart
Эксперт С++
7723 / 5632 / 549
Регистрация: 10.12.2010
Сообщений: 25,402
Записей в блоге: 17
22.08.2012, 21:10 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);
0
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:11  [ТС] 8
Пaтрик, не пойму как это сделать, ведь я должен указать только имя функции
0
Mиxaил
534 / 439 / 162
Регистрация: 10.12.2009
Сообщений: 1,857
22.08.2012, 21:11 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/ff81b81e964400d4c51cd4ae51313ce9

Добавлено через 34 секунды
или свою лямбду писать...
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:14  [ТС] 10
Цитата Сообщение от Avazart Посмотреть сообщение
list < ListChannel > :: iterator iteratorchannel;
iteratorchannel = remove_if( listchannel.begin(),listchannel.end(),HelpDeleteChannels);
Этот код у меня находиться в методе, а убрать нельзя
0
Avazart
Эксперт С++
7723 / 5632 / 549
Регистрация: 10.12.2010
Сообщений: 25,402
Записей в блоге: 17
22.08.2012, 21:16 11
Бросайте компилятор, код , бегите читать книги и не парьте нам мозг
1
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
22.08.2012, 21:30 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"));
}
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:31  [ТС] 13
Написал преподу, говорит необходимо сделать метод класса, который выступает в качестве предиката статическим, попробовал, все нормально, однако проблема в другом. В предикат, ведь можно передать только один параметр, а мне необходимо получить с поля ввода число, а вызвать нестатическую функцию из статического метода нельзя.
0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
22.08.2012, 21:33 14
Holsteng, в статическую функцию можно передать указатель на объект и через него дергать методы
еще учти, что remove_if не удаляет элементы
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
22.08.2012, 21:40  [ТС] 15
Спасибо! Но проблема в том что мне необходимо в предикате получить число из поля ввода, там же this не доступен, а в предикат более одного параметра нельзя передавать. Ребята проблема возникла из - за чего. Я удалял из list элементы в цикле и когда элемент оказывался последним вылетала ошибка, что невозможно инкремировать итератор.
0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
22.08.2012, 22:11 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?
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
23.08.2012, 13:26  [ТС] 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 можно применять с двумя итераторами, но никогда не использовал, подскажите, пжлста. Спасибо
0
Andsteadur
153 / 137 / 34
Регистрация: 23.05.2009
Сообщений: 275
23.08.2012, 14:24 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 начиная с этого итератора и заканчивая концом вектора.
1
Holsteng
47 / 10 / 2
Регистрация: 26.03.2012
Сообщений: 246
23.08.2012, 14:31  [ТС] 19
Спасибо, теперь я понял
0
23.08.2012, 14:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.08.2012, 14:31

Метод ближайшего соседа через STL Algorithm
Добрый день. Подскажите можно метод ближайшего соседа сделать через сортировку...

Имеется класс TAddList, унаследованный от stl-класса списка. Требуется написать метод добавления
Здравствуйте уважаемые специалисты. Помогите пожалуйста с решением задачи. ...

Правильное использование remove_if
Написал функцию, которая удаляет из последовательности типо vector элементы...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru