Re[2]: Обертки над const и не const объктом
От: night beast СССР  
Дата: 13.12.11 17:20
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Думаю, две сущности вместо одной — семантически вполне оправданное решение в данном случае. Дублирование конструкторов, тоже беда не большая. А вот const_cast — действительно некрасиво, я бы сделал как-то так:


не подойдет. у него конструктор постоянную строку принимает...
думаю самое простое решение -- передавать type_trait шаблонным параметром.
Re: Обертки над const и не const объктом
От: cppnick  
Дата: 13.12.11 19:55
Оценка:
Здравствуйте, enji, Вы писали:

E>Нельзя ли как-нибудь проще сделать?

Как вариант, можно сделать константность шаблонным параметром. Тем не менее, в Boost.Asio схожие концепты реализованы полностью раздельно.
Re[2]: Обертки над const и не const объктом
От: Кодт Россия  
Дата: 14.12.11 10:48
Оценка: 6 (2)
Здравствуйте, Chorkov, Вы писали:

C>Пусть константные/не константные методы класса, соотвсетуют константным/не константным методам обертки.

C>Изготавливать обертку двуия фабриками:
C>
C>shared_ptr<Foo>       make_foo(byte*);
C>shared_ptr<const Foo> make_foo(const byte*);
C>

C>Недостаток: закладываемся на определенную политику владения объектами.

Можем сделать другую политику
template<class T> class itself_ptr
{
  mutable T data_;
public:
  explicit itself_ptr(const T& src) : data_(src) {}

  T* operator->() const { return const_cast<T*>(&data_); }
  T& operator* () const { return const_cast<T&>( data_); }
};

здесь mutable и const_cast рассчитаны на то, что T — это обёртка, которую можно безболезненно копировать, как угодно.

Выбирая между itself_ptr<Wrapper> и itself_ptr<const Wrapper>, получаем желаемое.
Перекуём баги на фичи!
Re[3]: Обертки над const и не const объктом
От: uzhas Ниоткуда  
Дата: 14.12.11 11:52
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Можем сделать другую политику

имхо и без const_cast все шоколадно
http://ideone.com/5MnRf
http://ideone.com/xfenR
Re[4]: Обертки над const и не const объктом
От: Кодт Россия  
Дата: 14.12.11 12:27
Оценка:
Здравствуйте, uzhas, Вы писали:

К>>Можем сделать другую политику

U>имхо и без const_cast все шоколадно

да это я сперва наконсткастил, а потом про мутабле вспомнил
Перекуём баги на фичи!
Re: Резюме
От: enji  
Дата: 15.12.11 07:14
Оценка:
В общем, как я понял, самое прямое решение из предложенных вот такое:

template<class T> class itself_ptr
{
  mutable T data_;
public:
  explicit itself_ptr(const T& src) : data_(src) {}
 
  T* operator->() const { return &data_; }
  T& operator* () const { return data_; }
};

namespace detail {

struct TDBAddressImpl
{
  static int long_getter(const byte *buf);
  static void long_setter(byte *buf, double v);
};

}

template<class T>
class TDBAddress_
{
  T *buf_;
public:
  TDBAddress_(T *buf) : buf_(buf) {}
  
  byte getter() const { return buf_[105]; }
  void setter(byte v) { buf_[106] = v; }
  
  int long_getter() const { return detail::TDBAddressImpl::long_getter(buf_); }
};

typedef itself_ptr<TDBAddress_<byte> > TDBAddress;
typedef itself_ptr<TDBAddress_<const byte> > TDBAddressConst;

inline TDBAddress make_dbaddress(byte *buf) { return TDBAddress(TDBAddress_<byte>(buf)); }
inline TDBAddressConst make_dbaddress(const byte *buf) { return TDBAddressConst(TDBAddress_<const byte>(buf)); }


Его плюсы — нет const_cast и дублирования методов.
Его минусы
— нужны дополнительные заморочки, чтобы можно было преобразовать TDBAddress в TDBAddressConst
— itself_ptr можно вынести в библиотеку (если таких оберток будет много), но все равно много мусора — тайпдефы, make_dbaddress, отдельный struct для тяжелых функций, реализацию которых не охота светить в хидере, переадресация вызовов для таких функций.

ИМХО, исходное решение, хотя и не слишком красиво смотрится, вполне имеет право на жизнь
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.