Какую реализацию умных указателей вы используете? (C++)

Модератор: Модераторы разделов

_petya_
Сообщения: 53

Какую реализацию умных указателей вы используете?

Сообщение _petya_ »

Когда начал использовать умные указатели ( это случилось совсем недавно:) ), натолкнулся на тот неприятный факт, что auto_ptr в контейнерах STL использовать нельзя, да и вообще, убог он, auto_ptr.
Своего писать не хочется, т.к. интуиция подсказывает, что должно быть дофига всего готового.
По форуму шерстил "умные указатели", "умные ссылки" и т.д., информации крайне мало.
Поэтому, народ, поделитесь опытом, кто какие умные указатели использует (в частности, с STL).
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Какую реализацию умных указателей вы используете?

Сообщение serzh-z »

Никто ведь не запрещает написать свой умный указатель. Когда-то у меня был собственный шаблон, компактный и делающий всё то что мне было нужно, потом обнаружил, в то время только раскручивающийся, проект Boost с его shared_ptr, weap_ptr и прочии *_ptr...
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

_petya_ писал(а):
02.02.2008 16:13
Когда начал использовать умные указатели ( это случилось совсем недавно :) ), натолкнулся на тот неприятный факт, что auto_ptr в контейнерах STL использовать нельзя, да и вообще, убог он, auto_ptr.

auto_ptr не убог. Просто надо понимать, зачем он нужен, и когда его можно использовать.

Своего писать не хочется, т.к. интуиция подсказывает, что должно быть дофига всего готового.
По форуму шерстил "умные указатели", "умные ссылки" и т.д., информации крайне мало.
Поэтому, народ, поделитесь опытом, кто какие умные указатели использует (в частности, с STL).

Обычно используют boost. В нём есть ещё 4 типа умных указателей, думаю, вкупе со стандартным, этого хватит на все случаи жизни.
В следующем стандарте будут умные указатели из boost-а.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

_petya_ писал(а):
02.02.2008 16:13
auto_ptr в контейнерах STL использовать нельзя, да и вообще, убог он, auto_ptr.

в стл всё убого и подходит только для определенных задач, когда нужно сделать что то и побыстрей, это все конечно моё мнение. а лучше попробовать самому написать и опыта наберешся и покруче будет.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Какую реализацию умных указателей вы используете?

Сообщение Zeus »

wzrd писал(а):
02.02.2008 21:56
_petya_ писал(а):
02.02.2008 16:13
auto_ptr в контейнерах STL использовать нельзя, да и вообще, убог он, auto_ptr.

в стл всё убого и подходит только для определенных задач, когда нужно сделать что то и побыстрей, это все конечно моё мнение. а лучше попробовать самому написать и опыта наберешся и покруче будет.

Пишешь крутые связные списки? :D
STL как раз заточена на универсальность, а не на "определённые задачи".
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
02.02.2008 21:56
_petya_ писал(а):
02.02.2008 16:13
auto_ptr в контейнерах STL использовать нельзя, да и вообще, убог он, auto_ptr.

в стл всё убого и подходит только для определенных задач, когда нужно сделать что то и побыстрей, это все конечно моё мнение. а лучше попробовать самому написать и опыта наберешся и покруче будет.

Приведите пример, где проявляется убогость STL-я, и выигрывает ваш велосипед.
К STL-ю прибавим буст, ибо он фактически является стандартным дополнением, и очень многое попадает в следующий стандарт.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

библиотека algorythms убога... перебор, сортировка та же. лучше самому написать. а стандартное использовать тогда когда не важна производительность и нет особых ограничений. возьмем те же потоки, такая же картина, использование стандартного ввода/вывода преемущественно быстрей.
Пишешь крутые связные списки? :D
STL как раз заточена на универсальность, а не на "определённые задачи".

связные списки я даже если четсно не использовал оттуда. но есть подозрение что они проигрывают тем что ты сам напишешь. так же как и класс string (да он удобен, но опять же только в случае спешки).
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
03.02.2008 11:51
библиотека algorythms убога...

Чего в ней не хватает?

перебор, сортировка та же.

Чем плохи STL-евские перебор и сортировка?

лучше самому написать

Чем лучше?

а стандартное использовать тогда когда не важна производительность

Покажите пример, на котором стандартный алгоритм значительно проигрывает рукописному.

и нет особых ограничений.

Каких именно?

возьмем те же потоки, такая же картина, использование стандартного ввода/вывода преемущественно быстрей.

Потоки являются одним из видов стандартного ввода/вывода, так что предложение бессмысленно.
Если имелась в виду стандартная С-шная библиотека ввода-вывода, то она не расширяема в отличие от потоков, и является типонебезопасной.

связные списки я даже если четсно не использовал оттуда. но есть подозрение что они проигрывают тем что ты сам напишешь.

Не читал но осуждаю ©

так же как и класс string (да он удобен, но опять же только в случае спешки).

Чем плох класс string?

Вообще это всё похоже на какую-то религиозную ненависть. Ни единого факта, одни невнятные обвинения.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

вы издеваетесь? я сказал что это использование этих классов влияет на производительност.
1) вот вам задача: даны n координат. вычислить наиболее близкие друг к другу и расстояние между ними. входные данные: 0<n<=1000000000, далее координаты x1,x2...xn, где 0<x<=1000000000. выходные данные: номера координат и расстояние между ними (через пробел). Ограничения: 2 сек. 64 мб.
например
вход: 6
1 5 10 20 6 30
выход:1 [расстояние]
2 5 [номера коодинат]
уложить в ограничения используя qsort (он там самый быстрый). если надо тесты вышлю.
2) даны десять элементов, выведите все возможные перестановки элементов (без повторений).
уложитесь в одну секунду используя стловский перебор.
3)выведите в файл мегабайтов двадцать с помощью потоков и стандартного вывода (си без плюсов).
это что касается потоков.
4)со стрингов точно также. задачю дать?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

Ну вот совсем другое дело.
Сразу скажу, вы с чего то взяли, что я защищаю скорость iostreams, это конечно не так. iostreams медленней, с этим я не спорю, и это общепризнанный факт. Другое дело, что она, как я уже написал, типобезопасна и расширяема. В олимпиадных задачках этого конечно не заметно, но в реальном мире это заметно. И в 99% реальных задач скорость вывода не важна. Некоторые ваши задачки попадают в оставшися процент.

wzrd писал(а):
03.02.2008 13:57
2) даны десять элементов, выведите все возможные перестановки элементов (без повторений).
уложитесь в одну секунду используя стловский перебор.

Самое интересное в этой задаче то, что 99% времени занимает вывод. Вот моё решение, которое я считаю оптимальным:

Код: Выделить всё

   #include <algorithm>
   #include <unistd.h>

   #define BUF_SIZE 100

   int main() {
       char a[] = "0123456789\n";
       char buf[BUF_SIZE * 11];
       char* buf_pos = buf;

       do {
           memcpy(buf_pos, a, 11);
           buf_pos += 11;
           if (buf_pos == buf + BUF_SIZE * 11) {
               write(1, buf, BUF_SIZE * 11);
               buf_pos = buf;
           }
       } while (std::next_permutation(a, a + 10));

       return 0;
   }


Код: Выделить всё

$ time ./a.out > /dev/null
./a.out > /dev/null  0.07s user 0.00s system 94% cpu 0.076 total


Можете обратить внимание, что я даже не использовать C-шный ввод-вывод. С ним программа работала примерно в 5 раз медленней.
Сам алгоритм вычисления перестановок вполне себе STL-ный. Расскажите, что я сделал не так?

3)выведите в файл мегабайтов двадцать с помощью потоков и стандартного вывода (си без плюсов).
это что касается потоков.

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

4)со стрингов точно также. задачю дать?

Давайте.


Первую задачку пока подумаю, как сделать. Если вы не решили меня испытать на олимпиадное мышление (зря, я последний раз учавствовал в олимпиаде 4 года назад и давно всё забыл), можете сразу дать решение на чём-угодно, я попробую написать его на С++.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
03.02.2008 13:57
вы издеваетесь? я сказал что это использование этих классов влияет на производительност.
1) вот вам задача: даны n координат. вычислить наиболее близкие друг к другу и расстояние между ними. входные данные: 0<n<=1000000000, далее координаты x1,x2...xn, где 0<x<=1000000000. выходные данные: номера координат и расстояние между ними (через пробел). Ограничения: 2 сек. 64 мб.
например
вход: 6
1 5 10 20 6 30
выход:1 [расстояние]
2 5 [номера коодинат]
уложить в ограничения используя qsort (он там самый быстрый). если надо тесты вышлю.


Где то вы меня обманываете. Совершенно очевидно, что все координаты надо хранить в памяти. Их миллиард, каждая координата занимает 4 байта, значит нам нужно 4 гигабайта памяти. Довольно много для олимпиадной задачи. Может быть 0 < n < 1000000 ?

К тому же, если их миллиард, входные тестовые файлы будут занимать по нескольку гигабайтов. Один ввод будет несколько минут. Точно обманываете.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

за перебор я вам могу только похлопать. интересно. я вас не проверяю на умение решать задачи я просто приводил то с чем сталкивался.
string: были случаи когда изменение string'a на указатели давала лучшее время, что было критично. Задача тут.(ее можно и без строк конечно, но я про способ со строками.
извините если запарил со своими задачами, просто так легче
я исвлек вывод что если заниматься олимпиадами то STL пользоваться не желательно, а с другой стороны это неплохая помощь при разработке. я выложу вам исходник первой задачи когда перепишу (нужно сортировку поменять, я пузырьком делал).
Где то вы меня обманываете. Совершенно очевидно, что все координаты надо хранить в памяти. Их миллиард, каждая координата занимает 4 байта, значит нам нужно 4 гигабайта памяти. Довольно много для олимпиадной задачи. Может быть 0 < n < 1000000 ?

прошу прошения. я перепутал ограничения с координатами. 0 < n < 1000000 - это правильное ограничение.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
03.02.2008 15:19
за перебор я вам могу только похлопать. интересно. я вас не проверяю на умение решать задачи я просто приводил то с чем сталкивался.
string: были случаи когда изменение string'a на указатели давала лучшее время, что было критично. Задача тут.(ее можно и без строк конечно, но я про способ со строками.
извините если запарил со своими задачами, просто так легче
я исвлек вывод что если заниматься олимпиадами то STL пользоваться не желательно, а с другой стороны это неплохая помощь при разработке. я выложу вам исходник первой задачи когда перепишу (нужно сортировку поменять, я пузырьком делал).


Угу, вот и разобрались. Вы смотрите на STL с точки зрения его применения в олимпиадных задачках. Это совсем другое дело, но надо понимать, что олимпиадные задачи от реальных отличаются, и методы их решения тоже отличаются. На работе я могу три часа чай пить, обдумывая то, что надо сделать, а на олимпиаде кажая минута на счету (помните ведь, как в последние минуты судорожно пытаешься дописать задачу?). На работе мой код будут дописывать, модифицировать, искать в нём баги мои коллеги, на протяжении нескольких лет после его создания, на олимпиаде код никому не нужен, никому не нужны комментарии и осмысленные названия переменных. На олимпиаде важно написать задачу здесь и сейчас, на работе важно писать код, который будет расширяемым. На олимпиаде код тестируется на коленке, на работе я пишу юниттесты, тщательно покрывающие код.

Примерно по этим причинам я и считаю, что опыт решения олимпиадных задач к реальным задачам имеет мало отношения.

Относительно С++ в олимпиадах могу сказать следующее. Я лично олимпиадные задачки решал на паскале (потому что тогда ещё не знал С++), поэтому ниже только мои рассуждения:
iostreams - удобная штука, но медленная. Если надо считать 4 числа, вычислить что то и записать 4 числа, она вполне удобна. Если надо записать миллион чисел, лучше stdio.h.
STL-евские структуры данных - массивы, списки, деревья - довольно эффективны. Рукописныые их могут побить примерно в полтора раза, и то далеко не всегда. Зато в них нет ошибок, а в рукописных списках нередко путаешь указатели или забываешь про какую-нибудь глупость, и потом отлаживаешь минут 10 (а в олимпиаде 10 минут это много). Учитывая то, что грамотный алгоритм куда важнее ручных оптимизаций, я бы их использовал. Я уже не говорю о том, что написать нормальное дерево с балансировкой за полчаса действительно не так просто. А готовое STL-евское использовать - без проблем.
строки - фактически массив символов. Соотвественно у них такая же эффективность.
STL-евские алгоритмы, в большинстве своём, в олимпиадах не нужны. Исключения - std::sort, и ещё парочка наиболее часто употребляемых. Всё равно приходится всё писать руками.

Я лично написал не один класс вектора или списка на С++. И могу сказать, что STL-евские векторы и списки написаны довольно хорошо. Единственное НО - их нужно уметь использовать, понимать, почему ++i лучше i++, где может вызваться конструктор копирования, почему параметры надо передавать по ссылкам. Но когда всем этим владеешь, проблем особых возникать не должно.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

вот в этом я уже с вами согласен. кстати на счет потоков, я слышал что они уязвимы на переполнение буфера, это правда?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

прошу прошения. я перепутал ограничения с координатами. 0 < n < 1000000 - это правильное ограничение.

Тогда давайте ссылку на большой тест :)

wzrd писал(а):
03.02.2008 15:52
вот в этом я уже с вами согласен. кстати на счет потоков, я слышал что они уязвимы на переполнение буфера, это правда?



Если считывать в char*, то конечно уязвимы. Если, например, считывать в std::string, то не уязвимы.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

Вот решение первой задачи, на скорую руку. На чистом STL-е :) Я конечно переборщил, можно было проще, но раз вы настаивали :)

Код: Выделить всё

#include <algorithm>
#include <ext/algorithm>
#include <iostream>
#include <iterator>
#include <stdint.h>
#include <vector>


class Comparator {
public:
    Comparator(const std::vector<uint32_t>& a) : a(a) {}

    bool operator()(uint32_t v1, uint32_t v2) {
        return a[v1] < a[v2];
    }

private:
    const std::vector<uint32_t>& a;
};

class Generator {
public:
    Generator() : value(0) {}

    uint32_t operator()() {
        return value++;
    }

private:
    uint32_t value;
};

int main(void) {
    uint32_t len;
    std::cin >> len;

    std::vector<uint32_t> a(len);
    std::vector<uint32_t> index(len);

    __gnu_cxx::copy_n(std::istream_iterator<uint32_t>(std::cin), len, a.begin());
    std::generate(index.begin(), index.end(), Generator());

    std::sort(index.begin(), index.end(), Comparator(a));

    uint32_t min_i1 = 0;
    uint32_t min_i2 = 1;
    uint32_t min_d = abs(a[min_i1] - a[min_i2]);

    for (uint32_t i = 1; i < len; ++i) {
        const uint32_t i1 = index[i - 1];
        const uint32_t i2 = index[i];
        const uint32_t d = abs(a[i1] - a[i2]);
        if (d < min_d) {
            min_d = d;
            min_i1 = i1;
            min_i2 = i2;
            if (d == 0) {
                break;
            }
        }
    }

    std::cout << min_d << std::endl
        << std::min(min_i1, min_i2) + 1 << " "
        << std::max(min_i1, min_i2) + 1 << std::endl;

    return 0;
}
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

самый адский тест)

я потестирую и отпишусь. он мне кажется по времени не пройдет.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

Вот немного изменённая версия без iostream-ов :)

Код: Выделить всё

#include <algorithm>
#include <iterator>
#include <stdint.h>
#include <vector>


class Comparator {
public:
    Comparator(const std::vector<uint32_t>& a) : a(a) {}

    bool operator()(uint32_t v1, uint32_t v2) {
        return a[v1] < a[v2];
    }

private:
    const std::vector<uint32_t>& a;
};

class Generator {
public:
    Generator() : value(0) {}

    uint32_t operator()() {
        return value++;
    }

private:
    uint32_t value;
};

int main(void) {
    uint32_t len;
    scanf("%d", &len);

    std::vector<uint32_t> a(len);
    std::vector<uint32_t> index(len);

    for (uint32_t i = 0; i < len; ++i) {
        scanf("%d", &(a[i]));
    }

    std::generate(index.begin(), index.end(), Generator());

    std::sort(index.begin(), index.end(), Comparator(a));

    uint32_t min_i1 = 0;
    uint32_t min_i2 = 1;
    uint32_t min_d = abs(a[min_i1] - a[min_i2]);

    for (uint32_t i = 1; i < len; ++i) {
        const uint32_t i1 = index[i - 1];
        const uint32_t i2 = index[i];
        const uint32_t d = abs(a[i1] - a[i2]);
        if (d < min_d) {
            min_d = d;
            min_i1 = i1;
            min_i2 = i2;
            if (d == 0) {
                break;
            }
        }
    }
    printf("%d\n%d %d\n", min_d,
            std::min(min_i1, min_i2) + 1,
            std::max(min_i1, min_i2) + 1);

    return 0;
}



Код: Выделить всё

$ time ./a.out < 25
206
40394 89997
./a.out < 25  0.06s user 0.00s system 84% cpu 0.071 total
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

ответ правильный. очень впечатляет. я еще потом на других посмотрю. а на олимпиадах использовать СТЛ интересно можно, в частности библиотеку алгоритмов? меня очень привлекло.
можете посоветовать что нибудь почитать по ней?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
03.02.2008 16:56
ответ правильный. очень впечатляет. я еще потом на других посмотрю. а на олимпиадах использовать СТЛ интересно можно, в частности библиотеку алгоритмов? меня очень привлекло.

Вообще говоря можно, т.к. STL входит в стандарт С++.

Вот только, когда я учавствовал, в жюри иногда сидели некомпетентные идиоты, которые заявляли, что использование любых библиотек является нарушением, в том числе и STL, и не засчитывали задачи. Так что это зависит от вменяемости организаторов.

wzrd писал(а):
03.02.2008 16:56
можете посоветовать что нибудь почитать по ней?

http://anatolix.naumen.ru/Books/CPPSTL?v=dbl - там есть и оригинал и перевод.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: Какую реализацию умных указателей вы используете?

Сообщение wzrd »

v04bvs писал(а):
03.02.2008 17:01
Вообще говоря можно, т.к. STL входит в стандарт С++.
Вот только, когда я учавствовал, в жюри иногда сидели некомпетентные идиоты, которые заявляли, что использование любых библиотек является нарушением, в том числе и STL, и не засчитывали задачи. Так что это зависит от вменяемости организаторов.

а если библиотеки нельзя использовать то как выводить то? драйвер писать?) спасибо за ссылку кстати
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Какую реализацию умных указателей вы используете?

Сообщение v04bvs »

wzrd писал(а):
03.02.2008 17:02
v04bvs писал(а):
03.02.2008 17:01
Вообще говоря можно, т.к. STL входит в стандарт С++.
Вот только, когда я учавствовал, в жюри иногда сидели некомпетентные идиоты, которые заявляли, что использование любых библиотек является нарушением, в том числе и STL, и не засчитывали задачи. Так что это зависит от вменяемости организаторов.

а если библиотеки нельзя использовать то как выводить то? драйвер писать?)

Не знаю :) говорю же, идиоты.
Спасибо сказали:
netguard
Сообщения: 30

Re: Какую реализацию умных указателей вы используете?

Сообщение netguard »

а что у boost есть конкуренты ?
... есть же stl, все используют из него строки, списки, так зачем изобретать колесо, когда в boost все это тоже есть ?
Спасибо сказали: