Как хранить внешний объект в функторе?
От: Аноним  
Дата: 18.10.10 10:41
Оценка:
Привет!

Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими. Схематически моя ситуация выглядит так:

// Этот класс умеет сравнивать объекты типа Item, но он большого размера
class Big {
public:
    bool less_then(Item param1, Item param2);
};

// Хочу написать компаратор, чтобы использовать его в алгоритме sort для сортировки контейнера элементов типа Item
class my_comparator {
public:
    // Надо как-то передать ему внешний объект bigObj
    my_comparator( const Big& _bigObj ) : ??? // Но как именно не знаю
    { 
    }

    bool operator()(const Item& t1, const Item& t2) {
        return bigObj.less_then(t1, t2); // с помощью этого внешнего объекта сравниваем Item t1 и Item t2
    }
private:
    // Как хранить в данном компараторе внешний объект bigObj ?
}

// использование
void Foo::bar() {
    Big bigObj; // объект bigObj
    Initialize(bigObj); // инициализируем его, и т.п...

    // контейнер, который нужно сортировать
    vector<Item> v;
    // Заполняем v

    // для сортировки нужен функтор, который использует bigObj
    std::sort(v.begin(), v.end(), my_comparator (bigObj) );  
}


Как вариант можно хранить в my_comparator ссылку на bigObj:

class my_comparator {
public:
    my_comparator( const Big& _bigObj ) : bigObj (_bigObj)
    { 
    }
private:
    Big& bigObj;


Но что-то мне подсказывает, что это плохой вариант...

Спасибо.
Re: Как хранить внешний объект в функторе?
От: blackhearted Украина  
Дата: 18.10.10 10:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет!


А>Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими. Схематически моя ситуация выглядит так:


А>Как вариант можно хранить в my_comparator ссылку на bigObj:


А>Но что-то мне подсказывает, что это плохой вариант...


А>Спасибо.


Указатель?
Re: Как хранить внешний объект в функторе?
От: Stanislav V. Zudin Россия  
Дата: 18.10.10 10:59
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими.

<skipped>
А>Как вариант можно хранить в my_comparator ссылку на bigObj:
<skipped>
А>Но что-то мне подсказывает, что это плохой вариант...

А чем этот вариант плох? Нормальное решение. Рабочее.
_____________________
С уважением,
Stanislav V. Zudin
Re: Как хранить внешний объект в функторе?
От: Bell Россия  
Дата: 18.10.10 11:00
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>Как вариант можно хранить в my_comparator ссылку на bigObj:


А>
А>class my_comparator {
А>public:
А>    my_comparator( const Big& _bigObj ) : bigObj (_bigObj)
А>    { 
А>    }
А>private:
А>    Big& bigObj;
А>


А>Но что-то мне подсказывает, что это плохой вариант...


А что именно подсказывает? Мне вот например такой подход не кажется чем-то неправильным
Любите книгу — источник знаний (с) М.Горький
Re: Как хранить внешний объект в функторе?
От: MasterZiv СССР  
Дата: 18.10.10 11:08
Оценка: +1
On 18.10.2010 14:41, Аноним 820 wrote:

> Подскажите как поступить, если требуется использовать в функторе-компараторе

> внешний объект большого размера? Т.е. делать этот внешний объект членом-данных
> компаратора мне кажется не приемлимо — как минимум накладные расходы на
> копирование будут большими. Схематически моя ситуация выглядит так:
>

Так ссылку храни на этот объект. Функтор -- объект временный, нужный
только для работы алгоритма, определяется как правило локально, и
там хранить ссылку вполне допустимо.
Posted via RSDN NNTP Server 2.1 beta
Re: Как хранить внешний объект в функторе?
От: uzhas Ниоткуда  
Дата: 18.10.10 12:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет!

А>Но что-то мне подсказывает, что это плохой вариант...
прогоните это что-то куда подальше

Просыпаюсь сегодня утром,чувствую, что-то не то, и "что-то не то" тоже просыпается — "хочу кофе,хочу кофе!"

что-то
Re[2]: Как хранить внешний объект в функторе?
От: sheglov.nik  
Дата: 18.10.10 12:12
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>Как вариант можно хранить в my_comparator ссылку на bigObj:


А>>
А>>class my_comparator {
А>>public:
А>>    my_comparator( const Big& _bigObj ) : bigObj (_bigObj)
А>>    { 
А>>    }
А>>private:
А>>    Big& bigObj;
А>>


А>>Но что-то мне подсказывает, что это плохой вариант...


B>А что именно подсказывает? Мне вот например такой подход не кажется чем-то неправильным


Ну меня смущают такие сценарии
1.

my_comparator cmp1 (bigObj1);
my_comparator cmp2 (bigObj2);
cmp1 = cmp2; // Побочный эффект bigObj1 = bigObj2 ? Это нормально?

А если хранить константную ссылку, то я не смогу сделать оператор присваивания. Или STL не требует, чтобы функторы можно было присваивать?

2.
Big *pBigObj = new Big;
my_comparator cmp (*pBigObj);
delete pBigObj;
std::sort(v.begin(), v.end(), cmp );

Конечно не бог весть какой сценарий, но все же реализуемый...
Re[3]: Как хранить внешний объект в функторе?
От: Stanislav V. Zudin Россия  
Дата: 18.10.10 12:25
Оценка:
Здравствуйте, sheglov.nik, Вы писали:

B>>А что именно подсказывает? Мне вот например такой подход не кажется чем-то неправильным


SN>Ну меня смущают такие сценарии

SN>1.

SN>
SN>my_comparator cmp1 (bigObj1);
SN>my_comparator cmp2 (bigObj2);
SN>cmp1 = cmp2; // Побочный эффект bigObj1 = bigObj2 ? Это нормально?
SN>


И много ты компараторов присваиваешь?

Обычный сценарий:

std::sort(m_nets.begin(), m_nets.end(), FufelNetComparator(db.nets()));

Где "db" — большой-пребольшой объект, у которого есть объект EditorNet. Тоже очень большой.

А выше по коду

   class FufelNetComparator
   {
   public:
      FufelNetComparator(const fsed::EditorNet& nets) : m_net(nets){}
      bool operator()(const SAMPLE& n1, const SAMPLE& n2) const
      {
         return fsstr::RefDesCompare( m_net.NameNet(n1.second), m_net.NameNet(n2.second)) < 0;
      }
   private:
      const fsed::EditorNet& m_net;
   };
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Как хранить внешний объект в функторе?
От: uzhas Ниоткуда  
Дата: 18.10.10 12:30
Оценка: :)
Здравствуйте, sheglov.nik, Вы писали:

SN>Ну меня смущают такие сценарии


я вот подумываю использовать тип int в своих программах, но меня смущают следующие сценарии
1.
int i;
cout << i << endl; // выводит мусор. это нормально?


2.
int i = 0;
delete &i; // ассерты вываливаются, программа падает


3.
int i = 100000;
char x = i; // даже ворнинг не выводится, а число теряется
int y = x; // y != i


4.
int i = 3.1415;
cout << i; // не выводит знаки после запятой


возможно, это мелочи, но задуматься надо
Re[3]: Как хранить внешний объект в функторе?
От: uzhas Ниоткуда  
Дата: 18.10.10 12:42
Оценка: :)
Здравствуйте, sheglov.nik, Вы писали:


SN>Ну меня смущают такие сценарии

SN>1.

SN>
SN>my_comparator cmp1 (bigObj1);
SN>my_comparator cmp2 (bigObj2);
SN>cmp1 = cmp2; // Побочный эффект bigObj1 = bigObj2 ? Это нормально?
SN>

SN>А если хранить константную ссылку, то я не смогу сделать оператор присваивания. Или STL не требует, чтобы функторы можно было присваивать?

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

SN>2.

SN>
SN>Big *pBigObj = new Big;
SN>my_comparator cmp (*pBigObj);
SN>delete pBigObj;
SN>std::sort(v.begin(), v.end(), cmp );
SN>

здесь я вам могу порекомендовать запрет на удаление объектов (закрыть деструктор), а могу порекомендовать не писать на с++
С++ — язык, с помощью которого легко разорвать себе ногу, поэтому будьте внимательны
есть best-practices :
1) используйте интерфейсы, а не классы
2) не делайте в коде new\delete руками, всегда вызывайте фабрику для созданий объекта
3) не используйте сырые указатели, используйте смарт пойнтеры
4) оптимизируйте в самом конце
надежность кода улучшается, если следовать таким нехитрым советам
успехов
Re[2]: Как хранить внешний объект в функторе?
От: Erop Россия  
Дата: 18.10.10 15:05
Оценка: +1
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>А чем этот вариант плох? Нормальное решение. Рабочее.


С генеримым компилятором оператором присваивания могут быть сложности...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как хранить внешний объект в функторе?
От: Stanislav V. Zudin Россия  
Дата: 18.10.10 15:33
Оценка:
Здравствуйте, Erop, Вы писали:

SVZ>>А чем этот вариант плох? Нормальное решение. Рабочее.

E>С генеримым компилятором оператором присваивания могут быть сложности...

Ну в нашем-то случае он не потребуется. Поэтому сложностей не будет.
А вообще да.
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Как хранить внешний объект в функторе?
От: Erop Россия  
Дата: 18.10.10 16:35
Оценка: +1
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>А вообще да.

В общем, невладеющий указатель по всем статьям лучше, выходит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как хранить внешний объект в функторе?
От: Centaur Россия  
Дата: 18.10.10 17:57
Оценка: 6 (2)
Здравствуйте, sheglov.nik, Вы писали:

SN>Ну меня смущают такие сценарии

SN>1.

SN>my_comparator cmp1 (bigObj1);
SN>my_comparator cmp2 (bigObj2);
SN>cmp1 = cmp2; // Побочный эффект bigObj1 = bigObj2 ? Это нормально?


Для объектов с членами-ссылками не генерируется оператор присваивания по умолчанию. Как и для объектов с константными членами.

А по теме, надо либо держать указатель и следить, чтоб объект не удаляли; либо держать копию; либо вводить общее владение (shared_ptr или т.д.).
Re[3]: Как хранить внешний объект в функторе?
От: c-smile Канада http://terrainformatica.com
Дата: 18.10.10 18:25
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>С генеримым компилятором оператором присваивания могут быть сложности...


Сделать functor non-copyable если уж на то пошло.
Re[4]: Как хранить внешний объект в функторе?
От: Erop Россия  
Дата: 18.10.10 18:49
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Сделать functor non-copyable если уж на то пошло.

Зачем? Намного проще хранить указатель, а не ссылку...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Как хранить внешний объект в функторе?
От: c-smile Канада http://terrainformatica.com
Дата: 18.10.10 23:46
Оценка:
Здравствуйте, Erop, Вы писали:

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


CS>>Сделать functor non-copyable если уж на то пошло.

E>Зачем? Намного проще хранить указатель, а не ссылку...

Если functor copyable то тогда нужно разбираться с владением указателей. Т.е. как минимум shared_ptr или еще как-то.

А вообще по хорошему нужно разделять functors и callable objects. Последние допускают сохранение например в очередях за для deferred execution.
А просто functor он по смыслу non-copyable, как правило создается на стеке и сам передается по ссылкам. Поэтому и ссылки сам внутри может хранить. Как-то так, нет?
Re[6]: Как хранить внешний объект в функторе?
От: Erop Россия  
Дата: 19.10.10 04:53
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>А просто functor он по смыслу non-copyable, как правило создается на стеке и сам передается по ссылкам. Поэтому и ссылки сам внутри может хранить. Как-то так, нет?

Не понятно, зачем ссылки.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Как хранить внешний объект в функторе?
От: Bell Россия  
Дата: 19.10.10 05:02
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Сделать functor non-copyable если уж на то пошло.


Во все алгоритмы функтор передается по значению, так что это решение не пойдет.
Любите книгу — источник знаний (с) М.Горький
Re[5]: Как хранить внешний объект в функторе?
От: c-smile Канада http://terrainformatica.com
Дата: 19.10.10 05:26
Оценка: :)
Здравствуйте, Bell, Вы писали:

B>Во все алгоритмы функтор передается по значению, так что это решение не пойдет.


Упс...

Маразм если честно. Явная ошибка дизайна STL.
Re[6]: Как хранить внешний объект в функторе?
От: Тот кто сидит в пруду Россия  
Дата: 19.10.10 07:16
Оценка:
Здравствуйте, c-smile, Вы писали:

B>>Во все алгоритмы функтор передается по значению, так что это решение не пойдет.


CS>Упс...


CS>Маразм если честно. Явная ошибка дизайна STL.


Вообще-то специально так сделано, чтобы не терять скорость на косвенных обращениях.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: Как хранить внешний объект в функторе?
От: Bell Россия  
Дата: 19.10.10 07:36
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Маразм если честно. Явная ошибка дизайна STL.


здесь
Автор: Sergeem
Дата: 09.06.03
Любите книгу — источник знаний (с) М.Горький
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.