Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими. Схематически моя ситуация выглядит так:
// Этот класс умеет сравнивать объекты типа Item, но он большого размераclass Big {
public:
bool less_then(Item param1, Item param2);
};
// Хочу написать компаратор, чтобы использовать его в алгоритме sort для сортировки контейнера элементов типа Itemclass 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:
Здравствуйте, Аноним, Вы писали:
А>Привет!
А>Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими. Схематически моя ситуация выглядит так:
А>Как вариант можно хранить в my_comparator ссылку на bigObj:
А>Но что-то мне подсказывает, что это плохой вариант...
А>Спасибо.
Здравствуйте, Аноним, Вы писали:
А>Подскажите как поступить, если требуется использовать в функторе-компараторе внешний объект большого размера? Т.е. делать этот внешний объект членом-данных компаратора мне кажется не приемлимо — как минимум накладные расходы на копирование будут большими.
<skipped> А>Как вариант можно хранить в my_comparator ссылку на bigObj:
<skipped> А>Но что-то мне подсказывает, что это плохой вариант...
А чем этот вариант плох? Нормальное решение. Рабочее.
_____________________
С уважением,
Stanislav V. Zudin
On 18.10.2010 14:41, Аноним 820 wrote:
> Подскажите как поступить, если требуется использовать в функторе-компараторе > внешний объект большого размера? Т.е. делать этот внешний объект членом-данных > компаратора мне кажется не приемлимо — как минимум накладные расходы на > копирование будут большими. Схематически моя ситуация выглядит так: >
Так ссылку храни на этот объект. Функтор -- объект временный, нужный
только для работы алгоритма, определяется как правило локально, и
там хранить ссылку вполне допустимо.
Здравствуйте, sheglov.nik, Вы писали:
B>>А что именно подсказывает? Мне вот например такой подход не кажется чем-то неправильным
SN>Ну меня смущают такие сценарии SN>1.
SN>
SN>my_comparator cmp1 (bigObj1);
SN>my_comparator cmp2 (bigObj2);
SN>cmp1 = cmp2; // Побочный эффект bigObj1 = bigObj2 ? Это нормально?
SN>
здесь я вам могу порекомендовать запрет на удаление объектов (закрыть деструктор), а могу порекомендовать не писать на с++
С++ — язык, с помощью которого легко разорвать себе ногу, поэтому будьте внимательны
есть best-practices :
1) используйте интерфейсы, а не классы
2) не делайте в коде new\delete руками, всегда вызывайте фабрику для созданий объекта
3) не используйте сырые указатели, используйте смарт пойнтеры
4) оптимизируйте в самом конце
надежность кода улучшается, если следовать таким нехитрым советам
успехов
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>А чем этот вариант плох? Нормальное решение. Рабочее.
С генеримым компилятором оператором присваивания могут быть сложности...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
SVZ>>А чем этот вариант плох? Нормальное решение. Рабочее. E>С генеримым компилятором оператором присваивания могут быть сложности...
Ну в нашем-то случае он не потребуется. Поэтому сложностей не будет.
А вообще да.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>А вообще да.
В общем, невладеющий указатель по всем статьям лучше, выходит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, c-smile, Вы писали:
CS>Сделать functor non-copyable если уж на то пошло.
Зачем? Намного проще хранить указатель, а не ссылку...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, c-smile, Вы писали:
CS>>Сделать functor non-copyable если уж на то пошло. E>Зачем? Намного проще хранить указатель, а не ссылку...
Если functor copyable то тогда нужно разбираться с владением указателей. Т.е. как минимум shared_ptr или еще как-то.
А вообще по хорошему нужно разделять functors и callable objects. Последние допускают сохранение например в очередях за для deferred execution.
А просто functor он по смыслу non-copyable, как правило создается на стеке и сам передается по ссылкам. Поэтому и ссылки сам внутри может хранить. Как-то так, нет?
Здравствуйте, c-smile, Вы писали:
CS>А просто functor он по смыслу non-copyable, как правило создается на стеке и сам передается по ссылкам. Поэтому и ссылки сам внутри может хранить. Как-то так, нет?
Не понятно, зачем ссылки.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, c-smile, Вы писали:
B>>Во все алгоритмы функтор передается по значению, так что это решение не пойдет.
CS>Упс...
CS>Маразм если честно. Явная ошибка дизайна STL.
Вообще-то специально так сделано, чтобы не терять скорость на косвенных обращениях.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.