У меня есть свой класс строки с подсчетом ссылок. И вот иногда сидишь и думаешь как передавать строку в функцию?
void f(const char *str);
или
void f(const String &str );
Вообщем то и то другое далеко от идеала.
В первом случае если строка в функции "запоминается" теряется преимущество подсчета ссылок, а во втором строка может только юзатся на чтение, и создание временного обьекта String (malloc + memcpy) не оправданно.
Идея заключается в том чтобы завести отдельный класс для передачи строкового параметра StrBox и писать всегда обнообразно не думая:
void f(StrBox str);
Сам StrBox + фрагменты кода из String:
template <class T>
class StrBox_
{
public:
const T *cstr;
const bool smart;
public:
StrBox_( const T *str ) : cstr(str), smart(false) {}
StrBox_( const String_<T> &str ) : cstr(str), smart(true) {}
StrBox_( const T *str, bool smart ) : cstr(str), smart(smart) {}
StrBox_( const StrBox_ &sbx ) : cstr(sbx.cstr), smart(sbx.smart) {}
public:
operator const T* () const { return cstr; }
};
// конструктор и присваивание строки, если возможно юзается addref в противном случае copy:
template <class T>
String_<T>::String_( const StrBox_<T> &sbx )
{
if ( sbx.smart )
s_ = string_ref( (T*)sbx.cstr );
else
s_ = alloc_( sbx.cstr, str_len(sbx.cstr) );
}
template <class T> String_<T>&
String_<T>::operator = ( const StrBox_<T> &sbx )
{
if ( sbx.smart )
return reset_( string_ref( (T*)s.cstr ) );
else
return reset_(alloc_(sbx.cstr, str_len(sbx.cstr)));
}
P.S. Счастливые обладатели собственных string-велосипедов с подсчетом ссылок, могут заюзать и извлечь пользу. Для std::string такое не сделать.