Re: Как отделить константную ссылку от значения?
От: Кодт Россия  
Дата: 29.10.09 21:38
Оценка: 2 (1)
Здравствуйте, ChainEG, Вы писали:

Ниже много лирики, основная мысль в конце выделена жирным.


CEG>Я пытался перегрузить функцию Hold(), чтобы одна вызывалась для ссылок, а другая — для значений. Не выходит — в обоих случаях перегрузка разрешается в пользу какой-то одной функции, а не разных. Либо перегрузка вообще не разрешается.


Различать значения и ссылки очень, очень мучительно.
(Говорят, в C++0x есть rvalue references, но я в этом скорее осло, чем копенгаген).

Если ты имеешь дело с нульарными функциями, то можешь передавать не значение, а собственно функцию.
Выдрать тип из сигнатуры (T() или T const&()) — труда не составит.
Но это уж как-то совсем ограниченное решение.

CEG>Есть ли какие-то решения? Есть ли решение, пригодное для MSVC6 (ограниченная поддержка шаблонов, в частности, отсутствие частичной специализации)?


Мне кажется, правильно будет
1) Сперва задуматься — чем для тебя (в контексте твоей задачи) различаются ссылки и значения.
Ну, скажем, такое различие: значение, будучи временным объектом, живёт недолго; зато его можно копировать.

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

А так ли страшно, что глобальную ссылку нельзя копировать?
Вообще, — страшно: полиморфизм, всё-таки. Но если функции, возвращающие глобальные ссылки, не апкастят тип, эта проблема снимается.
И ещё раз страшно, если эксплуатируется уникальность адреса либо копирование слишком дорого.

2) Постараться каким-то способом придти к единообразию.
Единообразие в виде константных ссылок — ограничено, в силу проблемы времени жизни. (Кстати, из-за этого я проклял библиотеку Локи).
Единообразие в виде значений — это либо беспощадное копирование, либо использование прокси-объектов.
Наконец, можно достичь единообразия в виде умных указателей (тот же boost::shared_ptr может и с глобальными неубиваемыми объектами иметь дело). Куча плюсов и минус в виде нагрузки на динамическую память.

Прокси могут быть
— настоящими, в иерархии твоих TFubar'ов
— резко отличными по типу: начиная с банальных указателей вместо ссылок, и кончая boost::cref и его аналогами

Выбор техники зависит от того, насколько мучительно будет переделать программу.
Грубо говоря, если const Fubar& foo() заменить на cref<Fubar> foo() или на Fubar* foo() — много ли клиентского кода отвалится?
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.