Как хранить внешний объект в функторе?
От: Аноним  
Дата: 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.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.