Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
6 / 6 / 1
Регистрация: 04.12.2009
Сообщений: 42
1

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

16.07.2012, 23:22. Просмотров 2068. Ответов 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;
}
Вопрос: как сделать так, чтобы массив был отсортирован путем поправления ошибки?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.07.2012, 23:22
Ответы с готовыми решениями:

Std::vector<std::pair<std::vector<int>::iterator, std::vector<int>::iterator>
Вопрос по вектору. Допустим есть вектор, std::vector&lt;int&gt; vec; на каком - то этапе заполнения я...

Разыменование итератора std::list<vector<>>::iterator
Здравствуйте, есть код: list&lt;vector&lt;int&gt;&gt; L; L.push_front(vector&lt;int&gt;());...

Странная ошибка invalid initialization of non-const reference of type 'std::vector<oneVec>::iterator&
Пишу я значит двухмерный вектор, решаю проверить наличие ошибок(я просто компилирую) и выдают такую...

Разъясните код пжлст(выдает ошибку:cannot convert from 'class std::list<class c_bullet *,class std::allocator<class c_bullet *> >::iterator' to 'int')
Есть такие строки: std::list&lt;c_bullet*&gt; Bullets; ... for(auto i = Bullets.begin(); i !=...

13
бжни
2467 / 1676 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
16.07.2012, 23:35 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;
}
охренеть сколько ошибок я вам скажу
0
6 / 6 / 1
Регистрация: 04.12.2009
Сообщений: 42
16.07.2012, 23:44  [ТС] 3
Цитата Сообщение от alex_x_x Посмотреть сообщение

охренеть сколько ошибок я вам скажу
ну я набирал на форуме, а после уже решился скомпелить и норм вариант выложить, заране извеняюсь за предоставленные неудобства!!!
0
1450 / 787 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
17.07.2012, 00:09 4
Что я не могу понять, а почему без static не работает?
0
6 / 6 / 1
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:14  [ТС] 5
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что я не могу понять, а почему без static не работает?
"пес его знает", я на каком-то форуме вычитал, что MyMeth() должен быть функцией не принадлежащей классу, но этот вариант тоже не помогает
0
1450 / 787 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
17.07.2012, 00:14 6
Я хотел предложить вариант с лямбдой
C++
1
2
3
void Sort(){
        std::sort(vec_.begin(), vec_.end(), [] (Interface* i, Interface* j) {return i->GetI() < j->GetI();});
    }
0
6 / 6 / 1
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:16  [ТС] 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() сделать
0
бжни
2467 / 1676 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
17.07.2012, 00:25 8
Цитата Сообщение от yuron_477 Посмотреть сообщение
Что я не могу понять, а почему без static не работает?
потому что static member по сути является функцией, не-static member называются member-function и для них все по-другому работает (в смысле здесь уже нет обычных указателей на функцию, здесь member function pointer)
так как параметра два, то стандартными адаптерами не обойдешься - нужно заводить отдельный функтор итп
для этой задачи статик вполне сойдет
2
6 / 6 / 1
Регистрация: 04.12.2009
Сообщений: 42
17.07.2012, 00:36  [ТС] 9
со static работает
0
3 / 26 / 9
Регистрация: 29.08.2010
Сообщений: 204
17.07.2012, 00:59 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
    }
};
Не знаю норм или нет
0
DU
1492 / 1138 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2012, 02:08 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/
0
бжни
2467 / 1676 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
17.07.2012, 13:42 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;
}
0
DU
1492 / 1138 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2012, 17:33 13
в бусте мем_фн в большинстве случаев не обязательно втыкать. когда там смартпоинтер на объект в бинд отдают. может еще в каких-то. в новых плюсах наверно так же сделано. так что можно чуть проще:
std::sort(vec_.begin(), vec_.end(), std::bind(&C::MyMeth, this, _1, _2));
1
бжни
2467 / 1676 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
17.07.2012, 17:56 14
DU, ну это значит bind прокаченей чем я думал)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.07.2012, 17:56

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Исправить ошибку "Vector iterator not dereferancable"
Всех с наступающим Новым Годом! У меня возникла проблема с вот этой функцией (я пытаюсь...

STL, vector. iterator. как работает?
void invertArrange() //метод инвертирования порядка слов { ...

Vector<MyStruct> - как првильно объявить iterator
struct _1C { string Tag; string Rus; string Eng; _1C(const string &amp;Tag, const string &amp;Rus,...

Iterator в списке - как вывести на экран конкретный элемент списка?
Доброго времени суток! Недавно начал работу со списком в c++ и у меня возник вопрос:...


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

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

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