vector struct
От: Stals  
Дата: 26.03.10 19:17
Оценка:
struct Entry{
 std::string name;
 int number;
};

std::vector<Entry>book;

//во общем туда добавляются значения
//а перед выводом я хотел сделать сортировку по номеру телефона
int phoneSort(/*что мне передавать здесь?*/){
 struct Entry *ia=(struct Entry *)a;
 struct Entry *ib=(struct Entry *)b;
 return ia->number-ib->number;

}
main(){
 sort(book,bookLen,sizeof(struct Entry),phoneSort);

}

//bookLen увеличивается при добавлении новой записи

Может я еще что-то не так делаю..
добавил разметку — Кодт
vector struct
Re: vector struct
От: potapov.d  
Дата: 26.03.10 19:39
Оценка: +1 -1 :)
You do it wrong. Completely.

S> sort(book,bookLen,sizeof(struct Entry),phoneSort);


#include <algorithm>
#include <boost/bind.hpp>
...
std::sort(book.begin(), book.end(), boost::bind(&Entry::number, _1) < boost::bind(&Entry::number, _2));

phoneSort не нужен.
Re: vector struct
От: Alexey F  
Дата: 26.03.10 21:35
Оценка:
Здравствуйте, Stals, Вы писали:

S> sort(book,bookLen,sizeof(struct Entry),phoneSort);


Судя по имени — std::sort, судя по использованию — std::qsort (скорее, второе). Приведу примеры к обоим:
// Для qsort:
int phoneSort ( void const* left, void const* right ) {
    Entry const* leftEntry = static_cast<Entry const*> ( left ); // static_cast - более безопасный, нежели C-style cast ( struct Entry* )
    Entry const* rightEntry = static_cast<Entry const*> ( right );

    // -1, если меньше, 0, если равно и 1, если больше:
    if ( leftEntry->number < rightEntry->number ) {
        return -1;
    }
    else if ( leftEntry->number == rightEntry->number ) {
        return 0;
    }
    else {
        return 1;
    }
}


// Для std::sort:
struct SortByPhone {
    bool operator() ( Entry const& left, Entry const& right ) const {
        return left.number < right.number;
    }
};


#include <cstdlib> // для qsort
#include <algorithm> // для std::sort

// ...

std::vector<Entry> book;

int main () {
    // C-style:
    std::qsort ( &book[ 0 ], book.size (), sizeof ( Entry ), &phoneSort );

    // C++-style (рекомендую его):
    std::sort ( book.begin (), book.end (), SortByPhone () );
}


Re[2]: vector struct
От: strannik747  
Дата: 27.03.10 05:53
Оценка:
Здравствуйте, Alexey F, Вы писали:

AF>
AF>struct SortByPhone {
AF>    bool operator() ( Entry const& left, Entry const& right ) const {
AF>        return left.number < right.number;
AF>    }
AF>};
AF>



А разве не так?
bool operator() ( const Entry& left, const Entry& right ) const {
Re[2]: vector struct
От: Centaur Россия  
Дата: 27.03.10 06:00
Оценка: 1 (1)
Здравствуйте, Alexey F, Вы писали:

AF>Судя по имени — std::sort, судя по использованию — std::qsort (скорее, второе). Приведу примеры к обоим:


Поскольку qsort — функция стандартной библиотеки C и не имеет информации о типе элементов сортируемого массива (а только о размере), следует предположить, что она обменивает элементы через memcpy или memmove. Следовательно, её нельзя применять к не-POD-типам. Структура Entry содержит член типа std::string, не являющийся POD-типом.
Re[2]: vector struct
От: Кодт Россия  
Дата: 27.03.10 08:10
Оценка: 1 (1)
Здравствуйте, Alexey F, Вы писали:

AF>Судя по имени — std::sort, судя по использованию — std::qsort (скорее, второе). Приведу примеры к обоим:


Не надо приводить примеры для qsort! Она не имеет права сортировать не-POD-ы, потому что вместо честного swap делает побайтовый обмен. А для std::string это может быть разрушительно.
Перекуём баги на фичи!
Re[3]: vector struct
От: Кодт Россия  
Дата: 27.03.10 08:41
Оценка: -1
К>Не надо приводить примеры для qsort! Она не имеет права сортировать не-POD-ы, потому что вместо честного swap делает побайтовый обмен. А для std::string это может быть разрушительно.

http://codepad.org/KfaVSMzf — пример того, как qsort разрушает инвариант объекта. (this->myself==this)
Перекуём баги на фичи!
Re[3]: vector struct
От: Alexey F  
Дата: 27.03.10 09:25
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Не надо приводить примеры для qsort! Она не имеет права сортировать не-POD-ы, потому что вместо честного swap делает побайтовый обмен. А для std::string это может быть разрушительно.

Упс, точно, там std::string
Извиняюсь, параллельно код на C писал и мне там массив char померещился
Re[3]: vector struct
От: Alexey F  
Дата: 27.03.10 09:27
Оценка:
Здравствуйте, strannik747, Вы писали:

S>А разве не так?

S>
S>bool operator() ( const Entry& left, const Entry& right ) const {
S>


const T& и T const& в данном случае (с указателями будут нюансы) эквивалентны, это вопрос привычки
Re[4]: vector struct
От: Кодт Россия  
Дата: 27.03.10 10:18
Оценка:
Здравствуйте, Alexey F, Вы писали:

AF>const T& и T const& в данном случае (с указателями будут нюансы) эквивалентны, это вопрос привычки

Какие нюансы с указателями? const T* и T const* тоже идентичны.
Перекуём баги на фичи!
Re[5]: vector struct
От: Alexey F  
Дата: 27.03.10 11:10
Оценка:
Здравствуйте, Кодт, Вы писали:

AF>>const T& и T const& в данном случае (с указателями будут нюансы) эквивалентны, это вопрос привычки

К>Какие нюансы с указателями? const T* и T const* тоже идентичны.

// вторая версия сообщения[сегодня у меня явно не лады с разъяснениями]

T const* и const T* — конечно эквивалентны. Я имел ввиду:
const T*
T* const // не эквивалентны

Лично меня, когда я узнал впервые про "const справа" это запутало (как считал я вначале — "а, значит, просто переносим const вправо и всё работает"); Решив предупредить об этом человека, спросившего про
S>bool operator() ( const Entry& left, const Entry& right ) const {

это не расписал.
Re[4]: vector struct
От: skeptik_  
Дата: 27.03.10 22:28
Оценка:
Здравствуйте, Кодт, Вы писали:

К>>Не надо приводить примеры для qsort! Она не имеет права сортировать не-POD-ы, потому что вместо честного swap делает побайтовый обмен. А для std::string это может быть разрушительно.


К>http://codepad.org/KfaVSMzf — пример того, как qsort разрушает инвариант объекта. (this->myself==this)


искуственный пример. давайте пример как std::string разрушается.
Re[5]: vector struct
От: Кодт Россия  
Дата: 27.03.10 22:48
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>искуственный пример. давайте пример как std::string разрушается.


Запросто. Только на экзотических версиях STL.
Если string содержит буфер для маленькой строки сама в себе, и указатель на буфер — встроенный или внешний.
class string
{
  char *m_begin;
  size_t m_size, m_capacity;
  char m_buffer[BUFSIZE];

public:
  .....
};

После побайтового обмена — содержимое буферов обменяется, это правильно, но заодно — строки будут ссылаться не на свои буферы, а перекрёстно. Дальнейшая судьба объектов со сломанным инвариантом туманна и грустна.
Перекуём баги на фичи!
Re[6]: vector struct
От: skeptik_  
Дата: 27.03.10 22:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, skeptik_, Вы писали:


_>>искуственный пример. давайте пример как std::string разрушается.


К>Запросто. Только на экзотических версиях STL.


Ещё один искуственный пример skipped. Нормального примера не будет, насколько я понимаю.
Re[7]: vector struct
От: Erop Россия  
Дата: 27.03.10 23:34
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>Ещё один искуственный пример skipped. Нормального примера не будет, насколько я понимаю.


Не такой уж и искусственный. С MSVC вроде как одно время поставлялся STL с такой строкой...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: vector struct
От: Кодт Россия  
Дата: 28.03.10 07:41
Оценка: +1
Здравствуйте, skeptik_, Вы писали:

К>>Запросто. Только на экзотических версиях STL.


_>Ещё один искуственный пример skipped. Нормального примера не будет, насколько я понимаю.


Это не искусственный пример. Я с таким стрингом работал.
Внутренний буфер резко увеличивает производительность, снимая нагрузку с менеджера памяти.
Перекуём баги на фичи!
Re[8]: vector struct
От: skeptik_  
Дата: 28.03.10 09:26
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, skeptik_, Вы писали:


_>>Ещё один искуственный пример skipped. Нормального примера не будет, насколько я понимаю.


E>Не такой уж и искусственный. С MSVC вроде как одно время поставлялся STL с такой строкой...


Он до сих поставляется со small string optimization. Только делается она не столь нелепо, а через union указателя на внешний buffer и внутреннего buffer.
Re[8]: vector struct
От: skeptik_  
Дата: 28.03.10 09:27
Оценка: -2
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, skeptik_, Вы писали:


К>>>Запросто. Только на экзотических версиях STL.


_>>Ещё один искуственный пример skipped. Нормального примера не будет, насколько я понимаю.


К>Это не искусственный пример. Я с таким стрингом работал.


Это конечно не исключено, что какой-то ССЗБ такое написал, но обычно это делается через юнион.
Re[9]: vector struct
От: Кодт Россия  
Дата: 28.03.10 10:06
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>Это конечно не исключено, что какой-то ССЗБ такое написал, но обычно это делается через юнион.


Не ССЗБ, а тщательное профилирование.
Устойчивость к говнокоду не требовалась.
Перекуём баги на фичи!
Re[3]: vector struct
От: Тролль зеленый и толстый  
Дата: 28.03.10 12:41
Оценка: +1
C>Поскольку qsort — функция стандартной библиотеки C и не имеет информации о типе элементов сортируемого массива (а только о размере), следует предположить, что она обменивает элементы через memcpy или memmove. Следовательно, её нельзя применять к не-POD-типам. Структура Entry содержит член типа std::string, не являющийся POD-типом.

Кстати, распространенное заблуждение. POD здесь не при чем. Здесь важно лишь можно ли объект перемещать в памяти или нет. Существуют не POD-типы, которые можно перемещать, и POD-типы, которые нельзя перемещать (например, если в структуре имеется указатель, указывающий на одно из полей этой же структуры). Можно ли перемещать std::string, зависит от его реализации, вполне может быть, что можно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.