Здравствуйте, Awaken, Вы писали:
S>>Может какой-то другой? А есть ли другие? S>>Ну и конечно же — почему именно этот?
A>есть еще QString, XMLString и т.д.
MSDN о них не в курсе — самописные что ли?
или как-то иначе? S>Извините, а какая здесь проблема?
Ну код strstr( str, str ) фактически получит указатель на начало буфера внутри строки. Только сделает это не совсем заметно.
Соответсвенно когда ты отправишь этот указатель в operator +=, то может произойти разное. В том числе может так оказаться, что строка имеет специальную реализацию operator += ( const char* ), чтобы избежать лишнего копирования добавляемой строки. А вот защиты от передачи указателя внутрь своего буфера может и не быть (да и логично её не иметь, кстати)
Соответсвенно, когда стрка при конкатинации захочет переаллокировать свой буфер, переданный указатель может и устареть вообще-то...
E>>Ну там
CString str = "idfhkdsfjv";
E>>const char* text = str;
E>>str += text + str.GetLength() / 2;
S>И здесь не могли бы объяснить почему так писать не хорошо? str.Length() — не компилится кстати
Извини, правильно наверное так, если ты о ATL'ной строке, конечно . Просто вокруг так много строк...
А проблема ровно та же.
S>а что подразумевается под if (str) ? разве это нормальное использование класса? а почему кстати тут не генерируется сообщения об ошибке C2451 ?
Потому что происходит неявное пользовательсткое преобразование в const char*, который никогда не 0, кстати...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: удобное и функциональное использование строки в C++
include <string>
std::string
include <atlstr.h>
CString
S>Ну и конечно же — почему именно этот?
А для чего тебе нужны строки? Что за операции над ними ты планируешь делать? Как часто порождать/разрушшать и т. д.?
Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим
1) Удобстовом использования вместо const char*
2) Безопасностью того же
3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\
4) Возможностью организовать строку любых копибл элементов
и т. д.
Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать
Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой.
Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой
Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: удобное и функциональное использование строки в C++
Здравствуйте, Left2, Вы писали:
AA>>Вообще, я лично не знаю ни одной реализации STL, где std::basic_string не хранит элементы как contiguous block. AA>>В будущем это вроде бы вообще собираются в Стандарт добавить. L>Точно собираются добавить? С вектором не путаешь?
А>>По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=) E>А можно рассказать поподробнее? Что за проблемы, в каких контекстах?
проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип,
что может вызывать побочные эффекты
Re[3]: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
E>>Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим E>>1) Удобстовом использования вместо const char* E>>2) Безопасностью того же E>>3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\ E>>4) Возможностью организовать строку любых копибл элементов E>>и т. д.
E>>Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать E>>Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой. E>>Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой E>>Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
S>2) — вроде как в параллельной ветке так и не нашли причин опасности этого пункта — или имеется в виду что-то другое?.
Ну, например, тот же самый if( str )...
Ну и вообще, лёгкость неявного получения из объекта const char* многими рассматривается, как источник опасности. Типа нужно редко, а вредит часто. Некоторые наоборот считают, что это надо и удобно... S>3) — тоже не ясно
Ну вот есть у тебя API функция какакя-то, скажем GetUserName( char*, UINT* count ).
Вот хочешь ты получить из неё результат сразу в строку.
С одной строкой ты пишешь так
CString str;
UINT len = MAX_USER_NAME_LENGTH;
GetUserName( str.GetBuffer( len ), &len );
str.Release( len );
А с другой прийдётся использовать промежуточный буффер, как-то так:
vector<char> buffer;
UINT len = MAX_USER_NAME_LENGTH;
buffer.set_size( len + 1 );
GetUserName( &buffer[0], &len );
buffer.set_size( len );
buffer.push_back( 0 );
string str = &buffer[0]; // типа лишнее копирование :(
S>Хотелось бы чтобы код подобный этому работал: S>_putenv("myvar=" + var); //здесь происходит преобразование типа в std::string результирующей строки — а она уже в const char * автоматом преобразовываться не умеет.
Ну так string специально так спроектирована, чтобы обломать тебя
Тока так:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Awaken, Вы писали:
A>проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип, A>что может вызывать побочные эффекты
Приведи пример.
Что-то типа:
CString str;
str += stsstr( str, str );
или как-то иначе?
О чём идёт речь?
Казалось бы оба оператора ничего никуда не приводят, а просто приписывают в строку новое значение, или приписывают его в конец строки.
Единственный путь глюков, который я тут вижу, это сослаться на конец строки припомощи const char*, да этот вот указатель и передать в += того же объекта.
Ну там
CString str = "idfhkdsfjv";
const char* text = str;
str += text + str.Length() / 2;
Такой какой-то контекст?
Но это же понятно, что так писать нехорошо и опасно...
А как такая проблема может возникнуть в нормальном коде?
Или проблема вообще какая-то другая.
Скажем такая:
CString str;
if( str ) {
std::cout << "Ленин всегда с тобой, Ленин всегда живой...\n";
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: удобное и функциональное использование строки в C++
Я рекомендую вариант с std::string.
Почему?
1. Входит в стандарт — будет работать на любом совместимом компиляторе
2. Является частью стандартной библиотеки — сочетается со стандартными алгоритмами
Да здравствует мыло душистое и веревка пушистая.
Re: удобное и функциональное использование строки в C++
или как-то иначе?
Извините, а какая здесь проблема?
E>О чём идёт речь? E>Казалось бы оба оператора ничего никуда не приводят, а просто приписывают в строку новое значение, или приписывают его в конец строки. E>Единственный путь глюков, который я тут вижу, это сослаться на конец строки припомощи const char*, да этот вот указатель и передать в += того же объекта. E>Ну там
CString str = "idfhkdsfjv";
E>const char* text = str;
E>str += text + str.Length() / 2;
E>Такой какой-то контекст? E>Но это же понятно, что так писать нехорошо и опасно...
И здесь не могли бы объяснить почему так писать не хорошо? str.Length() — не компилится кстати
E>А как такая проблема может возникнуть в нормальном коде? E>Или проблема вообще какая-то другая. E>Скажем такая:
CString str;
E>if( str ) {
E> std::cout << "Ленин всегда с тобой, Ленин всегда живой...\n";
E>}
а что подразумевается под if (str) ? разве это нормальное использование класса? а почему кстати тут не генерируется сообщения об ошибке C2451 ?
Re[8]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Alex Alexandrov, Вы писали:
AA>>"Любое взятие адреса элемента" — не совсем корректно. Скорее, "любое получение неконстантной ссылки или указателя". Вот, собственно, код из libstdc++ (интересные месты выделены полужирным):
E>Ну и хорошего-то что? E>Как будто ты можешь свободно управлять константностью своих переменных...
Ну, это не было примером чего-то хорошего. Я было лишь иллюстрацией того, что использование std::string как contiguous block безопасно даже в случае ref-count реализации.
E>Хотя, использую прокси, можно таки сделать так, что при модификациях только будет копирование, но таки это всё неоправданное переусложнение, а с другой при взятии указателя всё равно никуда не денешься E>ИМХО всё
Насколько я знаю, Стандарт запрещает возвращать прокси. Точное место и обоснование времени нет искать, но где-то я читал про это.
E>Да, а что касается "стандартности", то CString не менее стандартен в целом. А если его немного порихтовать, чтобы сделать независимым, то можно его ещё и абсолютно переносимым сделать
Как обычно, все определяется требованиями. Если я пишу 50-строчный прототип какого-нибудь алгоритма или пример, то я буду использовать std::string. Если это большой проект, разные части которого могут быть скомпилированы разными компиляторами или я хочу (а я часто хочу), чтобы можно было дебажный билд какой-нибудь библиотеки накатить поверх релизной версии продукта, то я скажу строгое "нет" любым объектам STL по крайней мере во внешних интерфейсах. С легкостью могу представить ситуацию, когда использование std::string недопустимо даже в реализации. Так же легко могу себе представить, что у команды есть свой string, который им удобнее и лучше. Как обычно, все определяется требованиями. И возможностями.
It's kind of fun to do the impossible (Walt Disney)
удобное и функциональное использование строки в C++
Speakus пишет: > Подскажите, пожалуйста, какой класс лучше использовать для строк?
Ответа на ваш вопрос нет и быть не может. Потому что "зависит от"
многих-многих факторов. В первом приближении это должно быть std::string,
если у вам не будет проблем с производительностью.
Posted via RSDN NNTP Server 2.1 beta
Re: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
02.10.07 08:55
Оценка:
Здравствуйте, Speakus, Вы писали:
S>Здравствуйте, S>Подскажите, пожалуйста, какой класс лучше использовать для строк? S>include <string> S>std::string
S>include <atlstr.h> S>CString
S>Может какой-то другой? А есть ли другие? S>Ну и конечно же — почему именно этот?
По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=), поэтому в средних и больших проектах скорее всего буду использовать std::string и std::wstring.
Re: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
S>Здравствуйте, S>Подскажите, пожалуйста, какой класс лучше использовать для строк? S>include <string> S>std::string
S>include <atlstr.h> S>CString
S>Может какой-то другой? А есть ли другие? S>Ну и конечно же — почему именно этот?
имхо, юзал бы std::string , но как то приходилось реализовать свой класс строки,
чисто для своих нужд, без всяких излишеств, с обрезаным функционалом.
Re[2]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=)
А можно рассказать поподробнее? Что за проблемы, в каких контекстах?
Как-то странно, строка вещь часто используемая, должна бы быть отлажена...
Так что все косяки хочется знать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
A>>проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип, A>>что может вызывать побочные эффекты
E>Приведи пример.
s = s1 - s2 + s3;
// ↑ ой, должен был быть «+»
// а на самом деле это эквивалентно:
s = CString(LPCTSTR(ptrdiff_t(LPCTSTR(s1) - LPCTSTR(s2)) + LPCTSTR(s3)));
Или просто delete CString(). Или if(CString()) { }.
Здравствуйте, Roman Odaisky, Вы писали:
E>>Приведи пример.
RO>
RO>s = s1 - s2 + s3;
RO>// ↑ ой, должен был быть «+»
RO>// а на самом деле это эквивалентно:
RO>s = CString(LPCTSTR(ptrdiff_t(LPCTSTR(s1) - LPCTSTR(s2)) + LPCTSTR(s3)));
RO>
А что такое CString( int )?
RO>Или просто delete CString(). Или if(CString()) { }.
Вот с if я ещё понимаю, но это же просто клиника, так писать. А с delete, ИМХО, не страшно.
Так как delete в программах вообще аккуратно надо использовать, никто тебе не мешает ещё как-нибудь не то удалить, скажем так:
std::string str;
delete &str;
...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
E>А для чего тебе нужны строки? Что за операции над ними ты планируешь делать? Как часто порождать/разрушшать и т. д.?
E>Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим E>1) Удобстовом использования вместо const char* E>2) Безопасностью того же E>3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\ E>4) Возможностью организовать строку любых копибл элементов E>и т. д.
E>Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать E>Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой. E>Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой E>Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
Спасибо.
по пунктам
2) — вроде как в параллельной ветке так и не нашли причин опасности этого пункта — или имеется в виду что-то другое?.
3) — тоже не ясно
про стандартизацию — понял. Конечно лучше со стандартизацией чем без.
1) Скажите а нет ли возможности заставить работать string c const char* (ну т.е. получить выгоду пункта 1 — не теряя возможности использования GNU компиляторов) ?
пробовал двумя способами:
class mystring: public std::string
{
public:
mystring(const std::string & x) {*this = x;}
operator const char*() const {return this->c_str();}
};
и
operator const char*(const std::string &x) {return x.c_str();}
второй случай вообще не компилируется — нельзя видать делать преобразование типов не своего класса.
Хотелось бы чтобы код подобный этому работал:
mystring var("x");
_putenv("myvar=" + var); //здесь происходит преобразование типа в std::string результирующей строки — а она уже в const char * автоматом преобразовываться не умеет.
Re[3]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
03.10.07 11:11
Оценка:
Здравствуйте, Erop, Вы писали:
E>А можно рассказать поподробнее? Что за проблемы, в каких контекстах? E>Как-то странно, строка вещь часто используемая, должна бы быть отлажена... E>Так что все косяки хочется знать
Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
BOOL CReg::GetArray(CString strValueName, void * pArr, size_t sizeArr)
{
if(pArr && sizeArr && strValueName.GetLength())
{
CString strSK;
GetSubKeyString(strSK);
//
// it is essential to call Sleep(0) here
// because there is seems to be a bug in MSVC,
// and without Sleep(0) call
// functions GetSubKeyString && GetArray
// will not work properly
//
Sleep(0);
return GetArray(CReg::HKCU,
(LPCTSTR)strSK,
(LPCTSTR) strValueName,
pArr,
sizeArr);
}
return FALSE;
}
BOOL CReg::GetSubKeyString(CString& str)
{
CString s;
str = _T("Software\\");
str += CMfcieApp::_strRegKey;
str += _T("\\");
s.LoadString(AFX_IDS_APP_TITLE);
str += s;
str += _T("\\");
str += this->_strSubSectionName;
return TRUE;
}
Re[4]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
03.10.07 11:17
Оценка:
Здравствуйте, Аноним, Вы писали: А>Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
{}
ЗЫ
Вызывается это в InitInstance()
Re[3]: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
S>1) Скажите а нет ли возможности заставить работать string c const char* (ну т.е. получить выгоду пункта 1 — не теряя возможности использования GNU компиляторов) ?
А оно точно надо? Выгода очень сомнительна (С VisualAssist и ему подобными так вообще пофигу), а недостатки налицо.
Может стоит озаботиться решаемой задачей, а не играться в бирюльки..
Re[4]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
А ты уверен, что это в строке проблема?
Вот, напирмер, если на c-строке сделать (ну завести буффер в 10240 символов и strcat'ами собрать строчку), то без Sleep будет работать?
Я так понимаю, что в InitInstance окружение однопоточное?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
06.10.07 14:55
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
E>А ты уверен, что это в строке проблема? E>Вот, напирмер, если на c-строке сделать (ну завести буффер в 10240 символов и strcat'ами собрать строчку), то без Sleep будет работать?
Сейчас и без слипа заработало. Почему — не знаю Возможно, железо глючило тогда.
Все равно std::string удобнее при работе с контейнерами, там не хватает только форматирования. А с CString это не единственный глюк, попадались еще.
E>Я так понимаю, что в InitInstance окружение однопоточное?
Естественно.
Re[4]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
06.10.07 15:13
Оценка:
Здравствуйте, Erop, Вы писали:
E>UINT len = MAX_USER_NAME_LENGTH; E>GetUserName( str.GetBuffer( len ), &len ); E>str.Release( len ); [/c]
E>А с другой прийдётся использовать промежуточный буффер, как-то так:
vector<char> buffer;
E>UINT len = MAX_USER_NAME_LENGTH;
E>buffer.set_size( len + 1 );
E>GetUserName( &buffer[0], &len );
E>buffer.set_size( len );
E>buffer.push_back( 0 );
E>string str = &buffer[0]; // типа лишнее копирование :(
Ты перемудрил, так проще
const UINT len = MAX_USER_NAME_LENGTH;
TCHAR sz[len + 1];
STL_STR str; // STL_STR это либо std::string либо std::wstringif(GetUserName(sz, &len)) str = sz;
хотя избыточное копирование имеет место, но имена у вменяемых юзеров короткие.
Re[4]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
06.10.07 15:28
Оценка:
Здравствуйте, Erop, Вы писали:
E>А с другой прийдётся использовать промежуточный буффер, как-то так:
vector<char> buffer;
E>UINT len = MAX_USER_NAME_LENGTH;
E>buffer.set_size( len + 1 );
E>GetUserName( &buffer[0], &len );
E>buffer.set_size( len );
E>buffer.push_back( 0 );
E>string str = &buffer[0]; // типа лишнее копирование :(
Здесь строка E>buffer.push_back( 0 );
лишняя:
The GetUserName function retrieves the user name of the current thread. This is the name of the user currently logged onto the system.
[]
If the function succeeds, the return value is a nonzero value, and the variable pointed to by nSize contains the number of TCHARs copied to the buffer specified by lpBuffer, including the terminating null character.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Re[5]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Здесь строка E>>buffer.push_back( 0 ); А>лишняя
Соласен, но функция GetUserName тут просто для примера..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Ты перемудрил, так проще
А>
А>const UINT len = MAX_USER_NAME_LENGTH;
А>TCHAR sz[len + 1];
А>
Так можно только если размер буфера известен на стадии компиляции.
А если он запрашивается, то уже упс.
А>хотя избыточное копирование имеет место, но имена у вменяемых юзеров короткие.
Му мало ли какое API надо вызвать таким способом...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Сейчас и без слипа заработало. Почему — не знаю Возможно, железо глючило тогда. А>Все равно std::string удобнее при работе с контейнерами, там не хватает только форматирования. А с CString это не единственный глюк, попадались еще.
Неубедительно как-то.
А про конетейнеры тоже не понятно. Какая проблема хранить CString даже в STL-контейнерах?
Другое дело, что с CString нельзя (вернее неудобно) работать, как с STL-конетейнером. Например передовать её в различные алгоритмы.
Но мне не совсем понятно зачем это нужно делать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
07.10.07 12:58
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Сейчас и без слипа заработало. Почему — не знаю Возможно, железо глючило тогда. А>>Все равно std::string удобнее при работе с контейнерами, там не хватает только форматирования. А с CString это не единственный глюк, попадались еще.
E>Неубедительно как-то.
Можете не верить. Это не мои проблемы.
E>А про конетейнеры тоже не понятно. Какая проблема хранить CString даже в STL-контейнерах? E>Другое дело, что с CString нельзя (вернее неудобно) работать, как с STL-конетейнером. Например передовать её в различные алгоритмы. E>Но мне не совсем понятно зачем это нужно делать...
Ну, для начала CString нужно в контейнер вставить. Для std::string это просто.
Re[6]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
07.10.07 13:05
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Ты перемудрил, так проще
А>>
А>>const UINT len = MAX_USER_NAME_LENGTH;
А>>TCHAR sz[len + 1];
А>>
E>Так можно только если размер буфера известен на стадии компиляции. E>А если он запрашивается, то уже упс. А>>хотя избыточное копирование имеет место, но имена у вменяемых юзеров короткие. E>Му мало ли какое API надо вызвать таким способом...
Если он запрашивается, то для примерно в 50 — 90% случаев API есть аналог (возможно MFC), который в качестве [out] — параметра имеет тип CString&. Вообще это уже неконкретное обсуждение.
Re[6]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
07.10.07 13:16
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Здесь строка E>>>buffer.push_back( 0 ); А>>лишняя
E>Соласен, но функция GetUserName тут просто для примера..
А вы можете привести пример API — функции, которая возвращает строку, не оканчивающуюся нулем?
Re[7]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Если он запрашивается, то для примерно в 50 — 90% случаев API есть аналог (возможно MFC), который в качестве [out] — параметра имеет тип CString&. Вообще это уже неконкретное обсуждение.
И этотаналог написан через GetBuffer/ReleaseBuffer...
Тема-то была о том, что CString с таким API использовать удобнее, чем std::string...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: удобное и функциональное использование строки в C++
А>А для CString также просто?
А что за броблема будет, если заменить тут std::string на CString?
От элемента std::map вроде бы ничего не требует, кроме семантики значения, а она у CString как раз есть...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
E>Ну вот есть у тебя API функция какакя-то, скажем GetUserName( char*, UINT* count ). E>Вот хочешь ты получить из неё результат сразу в строку. E>С одной строкой ты пишешь так
CString str;
E>UINT len = MAX_USER_NAME_LENGTH;
E>GetUserName( str.GetBuffer( len ), &len );
E>str.Release( len );
E>А с другой прийдётся использовать промежуточный буффер, как-то так:
vector<char> buffer;
E>UINT len = MAX_USER_NAME_LENGTH;
E>buffer.set_size( len + 1 );
E>GetUserName( &buffer[0], &len );
E>buffer.set_size( len );
E>buffer.push_back( 0 );
E>string str = &buffer[0]; // типа лишнее копирование :(
Вообще, я лично не знаю ни одной реализации STL, где std::basic_string не хранит элементы как contiguous block. В будущем это вроде бы вообще собираются в Стандарт добавить. Так что с точки зрения практики код типа
вполне безопасен. В том числе и в реализациях с ref-counting буфера — получение ссылки на символ реализация обязана трактовать как потенциальную модификацию строки.
It's kind of fun to do the impossible (Walt Disney)
Re[5]: удобное и функциональное использование строки в C++
Здравствуйте, Alex Alexandrov, Вы писали:
AA>Вообще, я лично не знаю ни одной реализации STL, где std::basic_string не хранит элементы как contiguous block. В будущем это вроде бы вообще собираются в Стандарт добавить. Так что с точки зрения практики код типа
AA>
ИМХО отсутствие чего-то вроде GetBuffer/ReleaseBuffer -- косяк std::string. Опреация редкая. но нужная. Хрен ли её делать каким-то неявными нестандартными мульками --
AA>вполне безопасен. В том числе и в реализациях с ref-counting буфера — получение ссылки на символ реализация обязана трактовать как потенциальную модификацию строки.
Ну тоже хорошо, конечно. То есть любое взятие адреса элемента копирует разделяемый буфер?
Большое спасибо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Alex Alexandrov, Вы писали:
E>ИМХО отсутствие чего-то вроде GetBuffer/ReleaseBuffer -- косяк std::string. Опреация редкая. но нужная. Хрен ли её делать каким-то неявными нестандартными мульками --
Ну, у std::basic_string есть вообще только одно достоинство — то, что он стандартный. То, что реализация "недо" я абсолютно согласен. За одно то, что доступ к подстрокам по индексам использует npos (a.k.a. -1) значение, а не index-past-end как итераторы и как Java String, руки оторвать дизайнеру надо.
AA>>вполне безопасен. В том числе и в реализациях с ref-counting буфера — получение ссылки на символ реализация обязана трактовать как потенциальную модификацию строки. E>Ну тоже хорошо, конечно. То есть любое взятие адреса элемента копирует разделяемый буфер?
"Любое взятие адреса элемента" — не совсем корректно. Скорее, "любое получение неконстантной ссылки или указателя". Вот, собственно, код из libstdc++ (интересные месты выделены полужирным):
// Element access:
/**
* @brief Subscript access to the data contained in the %string.
* @param n The index of the character to access.
* @return Read-only (constant) reference to the character.
*
* This operator allows for easy, array-style, data access.
* Note that data access with this operator is unchecked and
* out_of_range lookups are not defined. (For checked lookups
* see at().)
*/const_referenceoperator[] (size_type __pos) const
{
_GLIBCXX_DEBUG_ASSERT(__pos <= size());
return _M_data()[__pos];
}
/**
* @brief Subscript access to the data contained in the %string.
* @param n The index of the character to access.
* @return Read/write reference to the character.
*
* This operator allows for easy, array-style, data access.
* Note that data access with this operator is unchecked and
* out_of_range lookups are not defined. (For checked lookups
* see at().) Unshares the string.
*/
reference
operator[](size_type __pos)
{
_GLIBCXX_DEBUG_ASSERT(__pos < size());
_M_leak();return _M_data()[__pos];
}
It's kind of fun to do the impossible (Walt Disney)
Re[3]: удобное и функциональное использование строки в C++
Здравствуйте, Alex Alexandrov, Вы писали:
AA>"Любое взятие адреса элемента" — не совсем корректно. Скорее, "любое получение неконстантной ссылки или указателя". Вот, собственно, код из libstdc++ (интересные месты выделены полужирным):
Ну и хорошего-то что?
Как будто ты можешь свободно управлять константностью своих переменных...
Хотя, использую прокси, можно таки сделать так, что при модификациях только будет копирование, но таки это всё неоправданное переусложнение, а с другой при взятии указателя всё равно никуда не денешься
ИМХО всё
Да, а что касается "стандартности", то CString не менее стандартен в целом. А если его немного порихтовать, чтобы сделать независимым, то можно его ещё и абсолютно переносимым сделать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
А>>typedef map<int, string, less<int> > INT2STRING; E>А что за броблема будет, если заменить тут std::string на CString? E>От элемента std::map вроде бы ничего не требует, кроме семантики значения, а она у CString как раз есть...
Вроде проблем не будет. Вот std::set<CString> — едва ли хорошая мысль.
До последнего не верил в пирамиду Лебедева.
Re[10]: удобное и функциональное использование строки в C++
Здравствуйте, Roman Odaisky, Вы писали:
RO>Вроде проблем не будет. Вот std::set<CString> — едва ли хорошая мысль.
А что за беда? Ну определи std::less для CString...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
09.10.07 04:19
Оценка:
Здравствуйте, Ужасть бухгалтера, Вы писали:
УБ>Ну, я могу. MultiByteToWideChar, например.
Бывает и такое. А вы ей на самом деле пользуетесь, или чем попроще, макросами типа W2A например?
Re[11]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
09.10.07 04:43
Оценка:
Здравствуйте, Erop, Вы писали:
RO>>Вроде проблем не будет. Вот std::set<CString> — едва ли хорошая мысль. E>А что за беда? Ну определи std::less для CString...
Это уже оверхед, о чем речь и шла.
Re[8]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
09.10.07 09:07
Оценка:
Здравствуйте, Erop, Вы писали:
E>И этотаналог написан через GetBuffer/ReleaseBuffer... E>Тема-то была о том, что CString с таким API использовать удобнее, чем std::string...
Если проект поддерживает mfc, то с API действительно да. Но в мфц есть свой контейнер для CString. Речь шла типа о том, что вообще лучше — танк или подводная лодка
Re[5]: удобное и функциональное использование строки в C++
AA>Вообще, я лично не знаю ни одной реализации STL, где std::basic_string не хранит элементы как contiguous block. AA>В будущем это вроде бы вообще собираются в Стандарт добавить.
Точно собираются добавить? С вектором не путаешь?
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[9]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Бывает и такое. А вы ей на самом деле пользуетесь, или чем попроще, макросами типа W2A например?
Я, например, пользуюсь. Макросы подобные избегаю обычно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Это уже оверхед, о чем речь и шла.
В смысле "оверхед"? Это же просто, делается один раз, и потом никаких проблем...
ИМХО надо при выборе смотреть на сами строчки, на то, наскольок удобно их использовать в твоих задачах, а не на то надо ли где-то написать одну функцию в одну строку размером...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
09.10.07 10:05
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Бывает и такое. А вы ей на самом деле пользуетесь, или чем попроще, макросами типа W2A например? E>Я, например, пользуюсь. Макросы подобные избегаю обычно...
Макро короче чем такая функция, с ними писать меньше надо. Мне писать длиннее обычно лениво, если можно короче написать. Люблю осциллировать!
Re[9]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>Макро короче чем такая функция, с ними писать меньше надо. Мне писать длиннее обычно лениво, если можно короче написать. Люблю осциллировать!
Ты эта, прости, но я обычно пишу так:
В одном месте в программе пишу:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском