Вопрос знатокам С++: Время жизни ссылки на template объект

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В том то и дело, что только в случае ссылки время жизни объекта увеличивается до пределов текущего блока. Во всех остальных случаях возвращаемый объект живёт только до завершения операции присваивания.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Да, ты прав. Но в случае _bstr_t твой пример выдаст ошибку даже если бы объект-результат жил до конца блока
HKarel
Сообщения: 25
Зарегистрирован: 07 дек 2004, 14:50

Хотел ответить на предпоследнее сообщение Eugie, но последние два сообщения и так все сказали :)
Тогда подъитожим: код Romeo должен заработать если его переписать следующим образом

Код: Выделить всё

_bstr_t GetSomeBSTRString(); 
... 
void SomeFunction() 
{ 
   ... 
   //char * strMyConvertedString = GetSomeBSTRString(); 
   //cout << strMyConvertedString; // access violation exception 
   _bstr_t &strMyConvertedString = GetSomeBSTRString(); 
   cout << strMyConvertedString.operator char*();
   ... 
}
Сложность - это мера непонимания.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

А почему cout<<GetSomeBSTRString(); не написать?
2B OR NOT(2B) = FF
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Дык, не умеет ostream с _bstr_t работать и vice versa
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Дык, не умеет ostream с _bstr_t работать и vice versa
У него же (у _bstr_t) есть оператор для неявного преобразования к char* ?
2B OR NOT(2B) = FF
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

А компилятор глупый, об этом не знает :) Без явного приведения никак (см. последнее сообщение HKarel)
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

_bstr_t str = L"Hello world\n";
std::cout<<str; // не компилируется
std::cout<<(char *)str; // компилируется

Хм, странно... Я помнится года 4 назад, когда был еще студентом, писал класс для работы с однобитными битмапами.
Дык я перегружал operator=(const bool val) и operator bool() cost в прокси - классе так, что конструкции вида

Код: Выделить всё

bw_bitmap(100,100) = true;
if (bw_bitmap(100,100)) {
 ...
}
Компилировались и работали.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Да, ты прав. Но в случае _bstr_t твой пример выдаст ошибку даже если бы объект-результат жил до конца блока.
Не выдаст. См. код _bstr_t. Выделенная под конвертацию строка удаляется лишь в деструкторе внутреннего класса, когда количество ссылок на контейнер BSTR строки не станет нулевым.
А компилятор глупый, об этом не знает. Без явного приведения никак (см. последнее сообщение HKarel)
Нет, компилятор не глупый. Он просто не знает какой оператор вызвать для того, чтобы вывести эту сроку. cout умеет выводить как обычные строки, так и BSTR строки, точно также, как и _bstr_t может интерпритироваться двояко, благодаря перегруженным в ней операторам приведения. Речь идёт не о глупости компилятора, а о том, что ситуация "ambigous" - неоднозначная. Если бы не это одно НО, то явного преобразования писать бы не пришлось. Естественно в данном надуманном случае лучше вообще использовать

Код: Выделить всё

cout << (BSTR)GetSomeBSTRString();
по той причине, что мы не будем тратить время на конвертацию.

И вообще, хватит обсуждать пример, который я написал с потолка :) . Ситуация, которая у меня возникла с год назад, конечно же была не идентичная. Я просто сделал набросок, чтобы показать общий принцип ошибки. Замечания типа "а почему бы нам не сделать так" - неуместны.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

2 Absurd
Не знаю, почему так. Могу только предположить, что в твоем случае ситуация с т.з. компилятора более определенная. Для ostream, наверное, накладно делать предположения о возможных неявных преобразованиях - потенциально их может быть слишком много.
Ответить