Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > передача вршменного объекта по некостантной ссылке


Автор: mes 29.5.2009, 21:15
тема возникла в результате обсуждения этой : http://forum.vingrad.ru/forum/topic-261305/anchor-entry1882413/15.html#st_0_view_0
компилирует ли VS
Код

struct A {};

A f1 () { return A(); }
void f2 (A& a) {}

int main(void)
{
  f2(f1());  // <-- это
  f2(A()); // <-- и это

  return 0;
}

Автор: zim22 29.5.2009, 21:26
Код

f2(f1);  // <-- это

error C2664: 'f2' : cannot convert parameter 1 from 'A (__cdecl *)(void)' to 'A &'

всё остальное компилируется.

если заменить на
Код

f2(f1());  // <-- это

то это тоже компилируется

Автор: azesmcar 29.5.2009, 21:29
Код

f2(f1);  // <-- это? - нет, ошибка
f2(A()); // <-- и это - да компилируется


Добавлено @ 21:29
mes

Учитывая то, что вероятно должно было быть написано так
Код

f2(f1());  // <-- это
f2(A()); // <-- и это

обе строки компилируются

товарищи, кто нибудь скиньте ссылку на разблокированнный стандарт..я замучаюсь вручную набирать (там же копирование заблокировано) smile все время забываю версию с работы домой притащить

Автор: mes 29.5.2009, 21:33
Цитата(azesmcar @  29.5.2009,  20:29 Найти цитируемый пост)

Учитывая то, что вероятно должно было быть написано так

да, там опечатка  smile 

Автор: mes 29.5.2009, 21:55
Цитата(azesmcar @  29.5.2009,  20:29 Найти цитируемый пост)
скиньте ссылку на разблокированнный стандарт

такой пойдет ? http://ftp.csci.csusb.edu/dick/c++std/cd2/

Добавлено через 2 минуты и 21 секунду
ну раз все компилирует, может и такое проглотит :
Код

A & ra = f1(); // f1() из первого примера

Автор: azesmcar 29.5.2009, 22:02
Цитата

The temporary to which the reference is
bound or the temporary that is the complete object to a subobject of which the temporary is bound persists
for the lifetime of the reference except as specified below. A temporary bound to a reference member in a
constructor’s ctorinitializer
(12.6.2) persists until the constructor exits. A temporary bound to a reference
parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.
A temporary bound to the returned value in a function return statement (6.6.3) persists until the function
exits.
 In all these cases, the temporaries created during the evaluation of the expression initializing the reference,
except the temporary to which the reference is bound, are destroyed at the end of the fullexpression
in which they are created and in the reverse order of the completion of their construction.

и такой эксперимент
Код

#include <iostream>

struct A
{
    int i_;
};

void f2 (A& a)
{
    a.i_ = 1;
}

int main(void)
{
    f2(A()); // <-- и это
    return 0;
}


компилируется, запускается..
из чего вывод, живет он дольше чем ему разрешает стандарт.

Добавлено через 1 минуту и 39 секунд
Цитата(mes @  29.5.2009,  21:55 Найти цитируемый пост)
такой пойдет ? http://ftp.csci.csusb.edu/dick/c++std/cd2/

Да  smile спасибо, хотя я уже не дождался и свой разблокировал smile 

Цитата(mes @  29.5.2009,  21:55 Найти цитируемый пост)
ну раз все компилирует, может и такое проглотит :

Да smile и это тоже..

Автор: mes 29.5.2009, 22:04
Цитата(azesmcar @  29.5.2009,  21:02 Найти цитируемый пост)
компилируется, запускается..
из чего вывод, живет он дольше чем ему разрешает стандарт. 

и такой код не является переносимым...

Добавлено @ 22:08
к тому же неизвестно, студия просто не контролирует передачу временного объекта, или все таки удлиняет его жизнь,
(надеюсь что второе) но все равно такой код потeнциально опасен. 

Автор: azesmcar 29.5.2009, 22:11
Цитата(mes @  29.5.2009,  22:04 Найти цитируемый пост)
и такой код не является переносимым... 

Абсолютно, но к сожалению непереносимым код делает далеко не только несоответствие стандарту.
Помнится в книге More Exceptional C++ Саттер писал о конструкции C++ целиком и полностью соответствующей стандарту, но компиляторов которые этот код проглотили оказалось меньшинство. Селяви smile

Добавлено @ 22:12
И в конце концов не будем забывать про
Цитата

A template defines a family of classes or functions.
template declaration:
export [opt] template < templateparameterlist> declaration

 smile

Добавлено через 4 минуты и 25 секунд
mes, 
Цитата(mes @  29.5.2009,  22:04 Найти цитируемый пост)
к тому же неизвестно, студия просто не контролирует передачу временного объекта, или все таки удлиняет его жизнь,

А это мы сейчас проверим.

Автор: mes 29.5.2009, 22:18
Цитата(azesmcar @  29.5.2009,  21:11 Найти цитируемый пост)
Абсолютно, но к сожалению непереносимым код делает далеко не только несоответствие стандарту.

да.. переносимость тут не при чем. Я имел ввиду под этим высказыванием немножко другое...
Что то типа этого : VS даже на таких элементарных примерах, позволяет писать ill-formed код, приучая к неправильным действиям.
т.е смысловой является последняя часть высказывания :
Код

такой код потeнциально опасен

Автор: azesmcar 29.5.2009, 22:18
Код

f2(A());

деструктор вызывается после завершения функции f2. Он удлиняет его жизнь.

Автор: mes 29.5.2009, 22:20
Цитата(azesmcar @  29.5.2009,  21:18 Найти цитируемый пост)

деструктор вызывается после завершения функции f2. Он удлиняет его жизнь.

в данном конкретном случае.. но нет гарантии что всегда smile

Автор: azesmcar 29.5.2009, 22:22
Цитата(mes @  29.5.2009,  22:18 Найти цитируемый пост)
VS даже на таких элементарных примерах, позволяет писать ill-formed код, приучая к неправильным действиям.


Таких примеров полно
Код

18.6.1 Class exception [lib.exception]
namespace std {
   class exception {
   public:
      exception() throw();
      exception(const exception&) throw();
      exception& operator=(const exception&) throw();
      virtual ~exception() throw();
      virtual const char* what() const throw();
   };
}

вот как описан класс exception в стандарте. И все же
Код

throw std::exception("error");

работает. Потому новичкам по моему лучше советовать писать на gcc.

Добавлено через 1 минуту и 21 секунду
Цитата(mes @  29.5.2009,  22:20 Найти цитируемый пост)
в данном конкретном случае.. но нет гарантии что всегда smile

Даже если всегда - это не смягчает вину smile

Добавлено через 9 минут и 36 секунд
А это вообще интересно
Код

struct A
{
};

A* f1 () { return &A(); }

int main(void)
{
    A* p = f1(); // f1() из первого примера
        //тут деструктор для обьекта уже вызван.
}

Автор: GoldFinch 29.5.2009, 22:36
вроде как передача манипулятора c параметрами в поток выглядит именно как

Код

class manip
{
public:
  manip(T arg_):arg(arg_){}
  some_stream& operator() (some_stream& s) { ... s<<arg;... }
private:
  T arg;
}

class some_stream
{
public:
 some_stream& operator<< (some_stream& s, manip m /*по значению*/) {return m(s);}
 ...
}

...
stream<<manip(1);

Автор: mes 29.5.2009, 22:45
GoldFinch, сорри, не уловил мысли, это вопрос или высказывание для продолжения дискуссии ?

Добавлено через 2 минуты и 33 секунды
Цитата(azesmcar @  29.5.2009,  21:22 Найти цитируемый пост)
  //тут деструктор для обьекта уже вызван.

как я понял, то студия для Т& старается обеспечивать требования уставляемые стандартом для Т const& по отношению к временному объекту.

Автор: azesmcar 29.5.2009, 22:52
mes

Ну с указателями он вроде себя правильно ведет..а с ссылками похоже на то.

Автор: mes 29.5.2009, 23:06
Цитата(azesmcar @  29.5.2009,  21:52 Найти цитируемый пост)
mes

Ну с указателями он вроде себя правильно ведет..а с ссылками похоже на то. 

если бы она еще умудрялась бы под указатели удлинять жизнь, то тогда и сборщик мусора не нужен был бы  smile 

Автор: azesmcar 29.5.2009, 23:10
редактировал, в этот момент интернет отключили smile 

Цитата(mes @  29.5.2009,  22:45 Найти цитируемый пост)
как я понял, то студия для Т& старается обеспечивать требования уставляемые стандартом для Т const& по отношению к временному объекту.


хотел дописать
а вот с ссылками похоже на то.
A& p = f1(); в студии ведет себя также как
const A& p = f1();
только неконстантный.

Цитата(mes @  29.5.2009,  23:06 Найти цитируемый пост)
если бы она еще умудрялась бы под указатели удлинять жизнь, то тогда и сборщик мусора не нужен был бы smile 

еще бы подсчет ссылок туда smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)