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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
Sanek911
4 / 4 / 0
Регистрация: 04.12.2009
Сообщений: 42
#1

std::sort(iterator, iterator, method) подскажите как исправить - C++

16.07.2012, 23:22. Просмотров 1392. Ответов 13
Метки нет (Все метки)

Уважаемые Знатоки!!! Вашему вниманию предоставляю код:

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "stdafx.h"
#include <vector>
#include <algorithm>
class Interface{
public:
    virtual ~Interface(){}
    virtual int GetI() = 0;
};
class A : public Interface{
    int i_;
public:
    A(int i): i_(i){}
    virtual int GetI(){
        return i_;
    }
};
 
class B : public Interface{
    int i_;
public:
    B(int i): i_(i){}
    virtual int GetI(){
        return i_;
    }
};
 
class C{
    std::vector<Interface*> vec_;
public:
    ~C(){
        for (std::vector<Interface*>::iterator it = vec_.begin(); it != vec_.end(); ++it)
            delete *it;
    }
    void AddElem(Interface* pI){
        vec_.push_back(pI);
    }
 
    bool MyMeth(Interface* i, Interface* j){
        return i->GetI() < j->GetI();
    }
 
    void Sort(){
        std::sort(vec_.begin(), vec_.end(), MyMeth); 
        //error C3867: C::MyMeth: в вызове функции отсутствует список аргументов; 
        //используйте "&C::MyMeth" для создания указателя на член
        //error C2780: void std::sort(_RanIt,_RanIt): требует аргументов: 2, имеется: 3
    }
};
 
void main(){
    C *pC = new C();
 
    pC->AddElem(new A(5));
    pC->AddElem(new A(3));
    pC->AddElem(new B(1));
    pC->AddElem(new B(2));
    pC->AddElem(new A(4));
    pC->Sort();
    
    delete pC;
}
Вопрос: как сделать так, чтобы массив был отсортирован путем поправления ошибки?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.07.2012, 23:22     std::sort(iterator, iterator, method) подскажите как исправить
Посмотрите здесь:

C++ string iterator
iterator to count C++
C++ deque iterator not dereferencable
Разыменование итератора std::list<vector<>>::iterator C++
Segmentation fault (iterator) C++
C++ STL, vector. iterator. как работает?
C++ Iterator
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alex_x_x
бжни
2443 / 1648 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
16.07.2012, 23:35     std::sort(iterator, iterator, method) подскажите как исправить #2
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class Interface{
public:
    virtual ~Interface(){}
    virtual int GetI() = 0;
};
class A : public Interface{
    int i_;
public:
    A(int i): i_(i) {}
    virtual int GetI(){
        return i_;
    }
};
 
class B : public Interface{
    int i_;
public:
    B(int i): i_(i){}
    virtual int GetI(){
        return i_;
    }
};
 
class C{
    std::vector<Interface*> vec_;
public:
    ~C(){
        for (std::vector<Interface*>::iterator it = vec_.begin(); it != vec_.end(); ++it)
            delete *it;
    }
    void AddElem(Interface* pI){
        vec_.push_back(pI);
    }
 
    static bool MyMeth(Interface* i, Interface* j){
        return i->GetI() < j->GetI();
    }
 
    void sort(){
        std::sort(vec_.begin(), vec_.end(), MyMeth); 
        //error C3867: C::MyMeth: в вызове функции отсутствует список аргументов; 
        //используйте "&C::MyMeth" для создания указателя на член
        //error C2780: void std::sort(_RanIt,_RanIt): требует аргументов: 2, имеется: 3
    }
};
 
int main(){
    C *pC = new C();
 
    pC->AddElem(new A(5));
    pC->AddElem(new A(3));
    pC->AddElem(new B(1));
    pC->AddElem(new B(2));
    pC->AddElem(new A(4));
    pC->sort();
    
    delete pC;
}
охренеть сколько ошибок я вам скажу
Sanek911
4 / 4 / 0
Регистрация: 04.12.2009
Сообщений: 42
16.07.2012, 23:44  [ТС]     std::sort(iterator, iterator, method) подскажите как исправить #3
Цитата Сообщение от alex_x_x Посмотреть сообщение

охренеть сколько ошибок я вам скажу
ну я набирал на форуме, а после уже решился скомпелить и норм вариант выложить, заране извеняюсь за предоставленные неудобства!!!
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
17.07.2012, 00:09     std::sort(iterator, iterator, method) подскажите как исправить #4
Что я не могу понять, а почему без static не работает?
Sanek911
4 / 4 / 0
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:14  [ТС]     std::sort(iterator, iterator, method) подскажите как исправить #5
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что я не могу понять, а почему без static не работает?
"пес его знает", я на каком-то форуме вычитал, что MyMeth() должен быть функцией не принадлежащей классу, но этот вариант тоже не помогает
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
17.07.2012, 00:14     std::sort(iterator, iterator, method) подскажите как исправить #6
Я хотел предложить вариант с лямбдой
C++
1
2
3
void Sort(){
        std::sort(vec_.begin(), vec_.end(), [] (Interface* i, Interface* j) {return i->GetI() < j->GetI();});
    }
Sanek911
4 / 4 / 0
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:16  [ТС]     std::sort(iterator, iterator, method) подскажите как исправить #7
Цитата Сообщение от yuron_477 Посмотреть сообщение
Я хотел предложить вариант с лямбдой
C++
1
2
3
void Sort(){
        std::sort(vec_.begin(), vec_.end(), [] (Interface* i, Interface* j) {return i->GetI() < j->GetI();});
    }
спасибо за вариант, этот вариант есть и желательно с MyMeth() сделать
alex_x_x
бжни
2443 / 1648 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
17.07.2012, 00:25     std::sort(iterator, iterator, method) подскажите как исправить #8
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что я не могу понять, а почему без static не работает?
потому что static member по сути является функцией, не-static member называются member-function и для них все по-другому работает (в смысле здесь уже нет обычных указателей на функцию, здесь member function pointer)
так как параметра два, то стандартными адаптерами не обойдешься - нужно заводить отдельный функтор итп
для этой задачи статик вполне сойдет
Sanek911
4 / 4 / 0
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:36  [ТС]     std::sort(iterator, iterator, method) подскажите как исправить #9
со static работает
HardMorg
2 / 25 / 3
Регистрация: 29.08.2010
Сообщений: 204
17.07.2012, 00:59     std::sort(iterator, iterator, method) подскажите как исправить #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
39
40
41
42
43
44
45
46
47
48
class Interface{
public:
    virtual ~Interface(){}
    virtual int GetI() = 0;
};
class A : public Interface{
    int i_;
public:
    A(int i): i_(i) {}
    virtual int GetI(){
        return i_;
    }
};
 
class B : public Interface{
    int i_;
public:
    B(int i): i_(i){}
    virtual int GetI(){
        return i_;
    }
};
 
class C{
    std::vector<Interface*> vec_;
public:
    ~C(){
        for (std::vector<Interface*>::iterator it = vec_.begin(); it != vec_.end(); ++it)
            delete *it;
    }
    void AddElem(Interface* pI){
        vec_.push_back(pI);
    }
 
    bool MyMeth(Interface* i, Interface* j){
        return i->GetI() < j->GetI();
    }
 
    void sort(){
        std::sort(vec_.begin(), vec_.end(), [&](Interface *i, Interface *j)->bool{
 
            return this->MyMeth(i, j);
        });
        //error C3867: C::MyMeth: в вызове функции отсутствует список аргументов; 
        //используйте "&C::MyMeth" для создания указателя на член
        //error C2780: void std::sort(_RanIt,_RanIt): требует аргументов: 2, имеется: 3
    }
};
Не знаю норм или нет
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2012, 02:08     std::sort(iterator, iterator, method) подскажите как исправить #11
делать функцию сравнения двух интерфейсов методом какого-то класса - по мне это кривовато.
такая функция является утилитной и может пригодится в других местах, в которых не будет никаких классов С. Логичнее сделать такую функцию свободной, можно даже прямо в файле, в котором декларируется интерфейс Interface и использовать ее для сортировки:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Interface{
public:
    virtual ~Interface(){}
    virtual int GetI() const = 0;
};
 
bool LessByI(const Interface* lhs, const Interface* rhs)
{
  return lhs->GetI() < rhs->GetI();
}
 
// где-то в другом месте, где понадобилась сортировка по I:
std::sort(begin, end, &LessByI); // просто передаем указатель на функцию
Если же так делать не хочется, то следующий по списку кандидат - функция в безымянном неймспейсе в спп файле, в котором реализуется класс С. В этом случае интерфейс класса С не засоряется лишними функциями.
Если и так не хочется, то далее такой метод лучше делать статическим, ведь внутри нет доступа ни к каким мемберам\методам класса С. Ну и когда такой доступ понадобится, то тут уже никуда не дется, придется делать метод нестатическим.

По лябмдам на харбре есть хорошая статья:
http://habrahabr.ru/post/66021/
alex_x_x
бжни
2443 / 1648 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
17.07.2012, 13:42     std::sort(iterator, iterator, method) подскажите как исправить #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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <functional>
#include <numeric>
#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
 
template <typename Comp, typename Pred>
struct Functor {
 
  typedef typename Comp::first_argument_type T;
  typedef typename Pred::argument_type       Z;
  typedef typename Comp::result_type         R;
    
  Functor (Comp _comp, Pred _pred) : comp(_comp), pred(_pred) { }
  R operator()(Z z1, Z z2) { 
     return comp(pred(z1), pred(z2)); 
  }
private:
  Comp comp;
  Pred pred;
};
 
template <typename Comp, typename Pred>
Functor<Comp, Pred> Generate(const Comp& comp, const Pred& pred) {
  return Functor<Comp, Pred>(comp, pred);
} 
 
struct A {
  A(int i) : m_i(i) {}
  int get_i() { return m_i; } 
private:
  int m_i; 
};
 
struct GetI : public std::unary_function  <A*,int> {
  int operator()(A* a) { return a->get_i(); }
};
 
int main() {
  std::vector<A*> v;
  v.push_back(new A(5));
  v.push_back(new A(3)); 
  v.push_back(new A(-3));  
  v.push_back(new A(7));   
  std::sort (v.begin(), v.end(), Generate(std::less<int>(), GetI()));
  std::transform (v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "), GetI());
}
Bash
1
-3 3 5 7
Добавлено через 9 часов 42 минуты
врооочем
на c++11 можно сделать оригинальный вариант

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <algorithm>
#include <functional>
 
using namespace std::placeholders;
 
class Interface{
public:
    virtual ~Interface(){}
    virtual int GetI() = 0;
};
class A : public Interface{
    int i_;
public:
    A(int i): i_(i) {}
    virtual int GetI(){
        return i_;
    }
};
 
class B : public Interface{
    int i_;
public:
    B(int i): i_(i){}
    virtual int GetI(){
        return i_;
    }
};
 
class C{
    std::vector<Interface*> vec_;
public:
    ~C(){
        for (std::vector<Interface*>::iterator it = vec_.begin(); it != vec_.end(); ++it)
            delete *it;
    }
    void AddElem(Interface* pI){
        vec_.push_back(pI);
    }
 
    bool MyMeth(Interface* i, Interface* j){
        return i->GetI() < j->GetI();
    }
 
    void sort(){
        std::sort(vec_.begin(), vec_.end(), std::bind(std::mem_fn(&C::MyMeth), this, _1, _2)); 
    }
};
 
int main(){
    C *pC = new C();
 
    pC->AddElem(new A(5));
    pC->AddElem(new A(3));
    pC->AddElem(new B(1));
    pC->AddElem(new B(2));
    pC->AddElem(new A(4));
    pC->sort();
    
    delete pC;
}
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2012, 17:33     std::sort(iterator, iterator, method) подскажите как исправить #13
в бусте мем_фн в большинстве случаев не обязательно втыкать. когда там смартпоинтер на объект в бинд отдают. может еще в каких-то. в новых плюсах наверно так же сделано. так что можно чуть проще:
std::sort(vec_.begin(), vec_.end(), std::bind(&C::MyMeth, this, _1, _2));
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.07.2012, 17:56     std::sort(iterator, iterator, method) подскажите как исправить
Еще ссылки по теме:

Iterator C++
C++ Iterator not deferencable
C++ Исправить ошибку "Vector iterator not dereferancable"
Iterator в списке - как вывести на экран конкретный элемент списка? C++
C++ Map iterator

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

Или воспользуйтесь поиском по форуму:
alex_x_x
бжни
2443 / 1648 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
17.07.2012, 17:56     std::sort(iterator, iterator, method) подскажите как исправить #14
DU, ну это значит bind прокаченей чем я думал)
Yandex
Объявления
17.07.2012, 17:56     std::sort(iterator, iterator, method) подскажите как исправить
Ответ Создать тему
Опции темы

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