STL - remove_if ()

Тема в разделе "LANGS.C", создана пользователем kool, 11 июл 2007.

  1. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    Привет всем!
    Помогите разобраться с remove_if для списка.
    Как определить свою ф-цию, которая выполняла
    то что делает прога текст которой приведен в приложении
    (он взят из MSDN). Но хотя результат вроде выдается правильный
    работает он не правильно, поскольку переопределенный оператор ()
    класса is_four_chars вобще нигде не выполняется, а выполняется
    оператор определенный в классе not_equal_to<string>, т.е. проверяется
    условие !=. Можно ли как-то создать свою функцию, которая и будет
    определять параметры элемента списка, например, как в этом примере.
    Всем спасибо за ответы.
     
  2. codewalker

    codewalker New Member

    Публикаций:
    0
    Регистрация:
    22 сен 2006
    Сообщения:
    11
    Переформулируй как-нибудь вопрос. Приведи пример непонятного кода.
     
  3. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    Видимо когда мой вопрос перекидывали из
    другой темы потеряли ссылку. Вот текст из MSDN

    Код (Text):
    1. include <list>
    2. #include <string>
    3. #include <iostream>
    4. using namespace std;
    5.  
    6. #if _MSC_VER > 1020   // if later than revision 4.2
    7. using namespace std;   // std c++ libs are implemented in std
    8. #endif
    9.  
    10. typedef list<string, allocator<string> > LISTSTR;
    11.  
    12. // Used to customize list::remove_if()
    13. class is_four_chars
    14.    : public not_equal_to<string>
    15. {
    16.    bool operator()(const string& rhs, const string&) const
    17.    {  return rhs.size() == 4; }
    18. };
    19.  
    20. void main()
    21. {
    22.    LISTSTR test;
    23.    LISTSTR::iterator i;
    24.  
    25.    test.push_back("good");
    26.    test.push_back("bad");
    27.    test.push_back("ugly");
    28.  
    29.    // good bad ugly
    30.    for (i = test.begin(); i != test.end(); ++i)
    31.       cout << *i << " ";
    32.    cout << endl;
    33.  
    34.    test.remove("bad");
    35.  
    36.    // good ugly
    37.    for (i = test.begin(); i != test.end(); ++i)
    38.       cout << *i << " ";
    39.    cout << endl;
    40.  
    41.    // remove any not equal to "good"
    42.    test.remove_if(binder2nd<not_equal_to<string> >
    43.       (not_equal_to<string>(), "good"));
    44.  
    45.    // good
    46.    for (i = test.begin(); i != test.end(); ++i)
    47.       cout << *i << " ";
    48.    cout << endl;
    49.  
    50.    // Remove any strings that are four characters long
    51.    test.remove_if(binder2nd<not_equal_to<string> >
    52.       (is_four_chars(), "useless parameter"));
    53.  
    54.    if (test.empty())
    55.       cout << "Empty list\n";
    56.  
    57. }
     
  4. K_O_T

    K_O_T New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2003
    Сообщения:
    25
    У меня ничего правильного код не выдал :) Поэтому!
    Код (Text):
    1. class is_four_chars
    2.    : public unary_function<string, bool>
    3. {
    4. public:
    5.    bool operator()(const string& str) const
    6.    {  return str.size() == 4; }
    7. };
    8.  
    9. //
    10. // ...
    11. //
    12.  
    13. test.remove_if(is_four_chars());
     
  5. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    Ваш код у меня тоже выдает ошибку:
    error C2664: 'remove_if' : cannot convert parameter 1 from 'class is_four_chars' to 'class std::binder2nd<struct std::not_equal_to<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>
    > > >'
    А вот код из MSDN компилится правильно, но работает
    не правильно.
    Спасибо за ответ.
     
  6. K_O_T

    K_O_T New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2003
    Сообщения:
    25
    Почитайте мой код внимательнее, особенно последнюю его строчку. Кроме реализации класса is_four_chars, поменялся вызов метода remove_if. В вызове не применяется binder2nd.

    Вот полный код. Компилируется и правильно работает в MSVS 2005.

    Код (Text):
    1. #include <list>
    2. #include <string>
    3. #include <iostream>
    4.  
    5. using namespace std;
    6.  
    7. class is_four_chars
    8.    : public unary_function<string, bool>
    9. {
    10. public:
    11.    bool operator()(const string& str) const
    12.    {  return str.size() == 4; }
    13. };
    14.  
    15. void main()
    16. {
    17.     typedef list<string> string_list;
    18.  
    19.     string_list test;
    20.     string_list::iterator it;
    21.  
    22.     test.push_back("good");
    23.     test.push_back("bad");
    24.     test.push_back("ugly");
    25.  
    26.     test.remove_if(is_four_chars());
    27.  
    28.     for (it = test.begin(); it != test.end(); ++it)
    29.       cout << *it << " ";
    30.    cout << endl;   
    31. }
     
  7. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    У меня VC6 и при компиляции вашего кода
    выдается ошибка
    error C2664: 'remove_if' : cannot convert parameter 1 from 'class is_four_chars' to 'class std::binder2nd<struct std::not_equal_to<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>
    > > >'
    С чем это может быть связано?
     
  8. K_O_T

    K_O_T New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2003
    Сообщения:
    25
    не понимаю откуда берутся std::binder2nd и std::not_equal_to в ошибке.
    Мы ведь не используем их. Правда?
     
  9. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    Видимо на VC6+sp5 глючит библиотека STL.
    Хотя ВАШ код проверял на разных машинах
    с VC6. На VC2005 и gcc под Винды все работает.
    А у вас какой компилер?
     
  10. K_O_T

    K_O_T New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2003
    Сообщения:
    25
    У меня VC2005.
    C VC6 не работал, я в С++ новичок. На такие вопросы обычно быстро и качественно отвечают на форуме RSDN.ru, там много опытных С++ программистов.
     
  11. kool

    kool New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    15
    Спасибо за все.