Re[3]: Возвращение константной ссылки
От: innochenti  
Дата: 30.12.11 21:11
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, rg45, Вы писали:


CS>А можно узнать что именно OK в этом коде:


CS>
CS>const std::string& s2 = function("Happy New Year!"); //OK!
CS>


CS>?


CS>Кроме как получение reference на временный объект ничего не вижу. В обоих случаях.



по-идеи в первом случае все будет ок, там кругом ссылка. так же?
второй случай отработает корректно, только если
const std::string& s2 = function(std::string("Happy New Year!"));
поправьте если не прав
Re[3]: Возвращение константной ссылки
От: rg45 СССР  
Дата: 30.12.11 21:27
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, rg45, Вы писали:


CS>А можно узнать что именно OK в этом коде:


CS>
CS>const std::string& s2 = function("Happy New Year!"); //OK!
CS>


CS>?


"OK" в этом коде то, что ссылка не перестает быть действительной, сразу же после инициализации, как это было бы, если бы существовал только первый вариант перегруженной функции.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: Возвращение константной ссылки
От: Анатолий Широков СССР  
Дата: 30.12.11 21:45
Оценка: +2 -2
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, rg45, Вы писали:


CS>А можно узнать что именно OK в этом коде:


CS>
CS>const std::string& s2 = function("Happy New Year!"); //OK!
CS>


CS>?


CS>Кроме как получение reference на временный объект ничего не вижу. В обоих случаях.


А продления времени жизни временного объекта, являющегося результатов выполнения перегруженной функции принимающей rvalue, не видно?
Re[4]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 30.12.11 22:38
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

CS>>Кроме как получение reference на временный объект ничего не вижу. В обоих случаях.


АШ>А продления времени жизни временного объекта, являющегося результатов выполнения перегруженной функции принимающей rvalue, не видно?


Нет, не видно. Может щательнее надо куда-то смотреть?

Вот эта программуля

#include <string>
#include <iostream>

const std::string& function(const std::string& str) 
{
    return str;
}

std::string function(std::string&& str) 
{
    return str;
}

int main(int argc, char* argv[])
{
  const std::string& s2 = function("Happy New Year"); 
  std::cout << "<" << s2 << ">" << std::endl;
  return s2.length();
}


Возвращает 0. Или падает. Как карта ляжет.
Вот вопрос у меня и возник — что значит тот OK?
Re[5]: Возвращение константной ссылки
От: rg45 СССР  
Дата: 30.12.11 22:46
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Анатолий Широков, Вы писали:


CS>>>Кроме как получение reference на временный объект ничего не вижу. В обоих случаях.


АШ>>А продления времени жизни временного объекта, являющегося результатов выполнения перегруженной функции принимающей rvalue, не видно?


CS>Нет, не видно. Может щательнее надо куда-то смотреть?


CS>Вот эта программуля


CS>
CS>#include <string>
CS>#include <iostream>

CS>const std::string& function(const std::string& str) 
CS>{
CS>    return str;
CS>}

CS>std::string function(std::string&& str) 
CS>{
CS>    return str;
CS>}

CS>int main(int argc, char* argv[])
CS>{
CS>  const std::string& s2 = function("Happy New Year"); 
CS>  std::cout << "<" << s2 << ">" << std::endl;
CS>  return s2.length();
CS>}
CS>


CS>Возвращает 0. Или падает. Как карта ляжет.


Падает, вероятно, от того, что у программы не нулевой код возврата, который, по видимому, расценивается как ошибка. Исправим это мелкое недоразумение и вот, уже ничего не падает: url=http://ideone.com/SvJEO
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 30.12.11 23:00
Оценка:
Здравствуйте, rg45, Вы писали:

CS>>Возвращает 0. Или падает. Как карта ляжет.


R>Падает, вероятно, от того, что у программы не нулевой код возврата, который, по видимому, расценивается как ошибка. Исправим это мелкое недоразумение и вот, уже ничего не падает: url=http://ideone.com/SvJEO


То же самое но в VC++ 2010 проделай.

В ём родимом если написать так (явно)

const std::string& s2 = function(std::string("Happy New Year"));

то срабатывает функция std::string function(std::string&& str);

Если же написать как ты нарисовал
const std::string& s2 = function("Happy New Year");

то уходим на const std::string& function(const std::string& str).

Честно говоря размышлять про то кто прав VC++ или GCС здесь даже и не хочется. Не для production сей кунштюк.
Re[7]: Возвращение константной ссылки
От: rg45 СССР  
Дата: 30.12.11 23:16
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>То же самое но в VC++ 2010 проделай.


CS>В ём родимом если написать так (явно)


CS>
CS>const std::string& s2 = function(std::string("Happy New Year")); 
CS>

CS>то срабатывает функция std::string function(std::string&& str);

CS>Если же написать как ты нарисовал

CS>
CS>const std::string& s2 = function("Happy New Year"); 
CS>

CS>то уходим на const std::string& function(const std::string& str).




К сожалению, десятки под рукой нет, попробовать не на чем, но охотно верю, что десятка ведет себя именно так.

CS>Честно говоря размышлять про то кто прав VC++ или GCС здесь даже и не хочется. Не для production сей кунштюк.


Размышлять тут особо не над чем: по-любому, тот же VC++ создал временный объект типа std::string (пусть даже неявно, что это меняет?), а потом для этого временного объекта неправильно выбрал кандидата на подстановку — очевидно, что неправ VC++.

CS>Не для production сей кунштюк.


Ну этот тезис неплохо бы хоть как-то аргументировать.
--
Справедливость выше закона. А человечность выше справедливости.
Re[8]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 30.12.11 23:42
Оценка:
Здравствуйте, rg45, Вы писали:

CS>>Честно говоря размышлять про то кто прав VC++ или GCС здесь даже и не хочется. Не для production сей кунштюк.


R>Размышлять тут особо не над чем: по-любому, тот же VC++ создал временный объект типа std::string (пусть даже неявно, что это меняет?), а потом для этого временного объекта неправильно выбрал кандидата на подстановку — очевидно, что неправ VC++.


CS>>Не для production сей кунштюк.


R>Ну этот тезис неплохо бы хоть как-то аргументировать.


Когда в коде ты видишь это
 function("Happy New Year");

то ты не можешь предсказать достоверно результат выражения.
Ты получаешь reference на временный объект которым неким магичесим образом будет иметь отметку "тянуть его до конца scope(?)". Причем в зависимости от фазы луны, используемого компайлера и его настроек. Шаманизм чистой воды — не для production.
Re[9]: Возвращение константной ссылки
От: rg45 СССР  
Дата: 31.12.11 00:10
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>>>Не для production сей кунштюк.


R>>Ну этот тезис неплохо бы хоть как-то аргументировать.


CS>Когда в коде ты видишь это

CS>
CS> function("Happy New Year"); 
CS>

CS>то ты не можешь предсказать достоверно результат выражения.
CS>Ты получаешь reference на временный объект которым неким магичесим образом будет иметь отметку "тянуть его до конца scope(?)". Причем в зависимости от фазы луны, используемого компайлера и его настроек. Шаманизм чистой воды — не для production.

Соглашусь, что на сегодня, по текущей степени соответствия компиляторов стандарту, а также с учетом того, что новые фишки языка еще не получили достаточно широкого распространения, что по ним еще не наработано того, что называется "Best Practices", в продакшн такие вещи пока пускать не разумно. В особенности, если необходимо поддерживать переносимость кода. Но если на минуточку заглянуть в то счастливое будущее, когда компиляторы достаточно сносно будут выдерживать каноны, то, ИМХО, подобный код не должен вызывать каких-либо затруднений. Ведь достаточно взглянуть только на объявления этих перегрузок, что бы понять, что значения, возвращаемые этим семейством функций можно безопасно использовать для инициализации константных ссылок. И что при этом можно даже не задумываться о том, с каким объектом будет связана ссылка в том или ином случае — автоматическим, статическим или временным.
--
Справедливость выше закона. А человечность выше справедливости.
Re[8]: Возвращение константной ссылки
От: Masterkent  
Дата: 31.12.11 06:57
Оценка:
hmich:

H>
class X1
H>{
H>public:
H>    Result const &f() const;
H>    ....
H>};

H>class X2
H>{
H>public:
H>    Result f() const;
H>    ....
H>};

H>template < class X > void foo(X const &x)
H>{
H>    Result const &result = x.f();
H>    ....
H>}


H>В этом случае foo работает с одинаковой производительностью и с X1, и с X2. Если мы принимаем результат функции по значению, то в случае с X1 мы получаем лишнее копирование.


Это довольно специфический случай (причём сколь-нибудь заметное влияние такого лишнего копирования на производительность программы делает его ещё более специфическим). Мой поинт в том, что решение о выборе между Result const r = function(), Result const &r = function() и прочими вариантами должно приниматься в индивидуальном порядке, а те, кто используют Result const &r = function() на автопилоте, пускай пеняют на себя в случае чего.
Re[7]: Возвращение константной ссылки
От: Masterkent  
Дата: 31.12.11 06:58
Оценка: 3 (1)
c-smile:

CS>Здравствуйте, rg45, Вы писали:


CS>>>Возвращает 0. Или падает. Как карта ляжет.


R>>Падает, вероятно, от того, что у программы не нулевой код возврата, который, по видимому, расценивается как ошибка. Исправим это мелкое недоразумение и вот, уже ничего не падает: url=http://ideone.com/SvJEO


CS>То же самое но в VC++ 2010 проделай.


CS>В ём родимом если написать так (явно)


CS>
CS>const std::string& s2 = function(std::string("Happy New Year")); 
CS>

CS>то срабатывает функция std::string function(std::string&& str);

CS>Если же написать как ты нарисовал

CS>
CS>const std::string& s2 = function("Happy New Year"); 
CS>

CS>то уходим на const std::string& function(const std::string& str).

Похожий пример я уже приводил тут
Автор: Masterkent
Дата: 30.09.11
. Дело в том, что с момента выхода VC++ 10.0 до окончательного утверждения стандарта C++11 некоторые правила уже успели усовершенствовать. VC++ 10.0 — это компилятор с сырой и довольно скромной поддержкой неких устаревших draft-ов C++0x, оценивать по нему возможности C++11 некорректно.
Re[9]: Возвращение константной ссылки
От: hmich  
Дата: 31.12.11 12:17
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Это довольно специфический случай (причём сколь-нибудь заметное влияние такого лишнего копирования на производительность программы делает его ещё более специфическим).


Случай вполне обычный, когда X инкапсулирует тяжелый объект и предоставляет к нему константный доступ. При этом изначально этот объект мог быть легким и возвращаться при необходимости по значению.

M>Мой поинт в том, что решение о выборе между Result const r = function(), Result const &r = function() и прочими вариантами должно приниматься в индивидуальном порядке, а те, кто используют Result const &r = function() на автопилоте, пускай пеняют на себя в случае чего.


Мой пойнт был в выражении поддержки ononim. Для меня тоже Result const &r = function() будет кодом по умолчанию, а нарисованная выше функция function — специфичным случаем. Более того, грабли такой реализации функции довольно известны, и являются частным случаем "подумать, прежде чем возвращать значение из функции по ссылке".
Re[8]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 31.12.11 17:36
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Похожий пример я уже приводил тут
Автор: Masterkent
Дата: 30.09.11
. Дело в том, что с момента выхода VC++ 10.0 до окончательного утверждения стандарта C++11 некоторые правила уже успели усовершенствовать. VC++ 10.0 — это компилятор с сырой и довольно скромной поддержкой неких устаревших draft-ов C++0x, оценивать по нему возможности C++11 некорректно.


Семантически это вот:
  std::string function(std::string&& str) { return str; }
  const std::string& s1 = function("Happy New Year");


эквивалентно этому:
  const std::string& s2 = std::string("Happy New Year");


Вопрос: являются ли эти два выражения тождественными с точки зрения C++11?
Re[9]: Возвращение константной ссылки
От: alexeiz  
Дата: 02.01.12 03:42
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Семантически это вот:

CS>
CS>  std::string function(std::string&& str) { return str; }
CS>  const std::string& s1 = function("Happy New Year"); 
CS>


CS>эквивалентно этому:

CS>
CS>  const std::string& s2 = std::string("Happy New Year"); 
CS>


CS>Вопрос: являются ли эти два выражения тождественными с точки зрения C++11?


В первом случае вызывается конструктор string из char const *, а за ним move-конструктор string. Во втором просто конструктор string.
Re[10]: Возвращение константной ссылки
От: Masterkent  
Дата: 03.01.12 19:50
Оценка:
hmich:

M>>Это довольно специфический случай (причём сколь-нибудь заметное влияние такого лишнего копирования на производительность программы делает его ещё более специфическим).


H>Случай вполне обычный, когда X инкапсулирует тяжелый объект и предоставляет к нему константный доступ. При этом изначально этот объект мог быть легким и возвращаться при необходимости по значению.


Я уже указал на то, что такое изменение интерфейса является потенциальным breaking change, причём недиагностируемым на этапе трансляции (т.е. надо заново всё тщательно тестировать, а случае обнаруженного fail-а — ещё и тратить усилия на поиски новоиспечённого бага). Подобные изменения с целью какой-то мелкой оптимизации я бы у себя допускать не стал.
Re[10]: Возвращение константной ссылки
От: Masterkent  
Дата: 03.01.12 19:52
Оценка:
alexeiz:

A>Здравствуйте, c-smile, Вы писали:


CS>>Семантически это вот:

CS>>
CS>>  std::string function(std::string&& str) { return str; }
CS>>  const std::string& s1 = function("Happy New Year"); 
CS>>


CS>>эквивалентно этому:

CS>>
CS>>  const std::string& s2 = std::string("Happy New Year"); 
CS>>


CS>>Вопрос: являются ли эти два выражения тождественными с точки зрения C++11?


A>В первом случае вызывается конструктор string из char const *, а за ним move-конструктор string.


Не move, а copy. Если function определить так

std::string function(std::string&& str) { return std::move(str); }

то тогда будет перемещение.
Re[10]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 03.01.12 22:08
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>В первом случае вызывается конструктор string из char const *, а за ним move-конструктор string. Во втором просто конструктор string.


Я правильно понимаю идею что теперь (в C++11) эти двы выражения

const std::string s1("Happy New Year");
const std::string& s2 = std::string("Happy New Year");


эквивалентны?
Re[11]: Возвращение константной ссылки
От: Masterkent  
Дата: 04.01.12 09:00
Оценка:
c-smile:

CS>Я правильно понимаю идею что теперь (в C++11) эти двы выражения


CS>
CS>const std::string s1("Happy New Year");
CS>const std::string& s2 = std::string("Happy New Year");
CS>


CS>эквивалентны?


Это не выражения, а определения, и в целом они не эквивалентны, т.к. объявляемые сущности имеют разные имена и разные declared types (которые можно получить с помощью оператора decltype). К ссылке не может применяться NRVO. Если это member-ы некоего пространства имён, имеющего внешнее связывание, то у них будет разное связывание.
Re[8]: Возвращение константной ссылки
От: Сыроежка  
Дата: 04.01.12 19:55
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Сыроежка, Вы писали:


С>>Здравствуйте, rg45, Вы писали:


R>>>Здравствуйте, Сыроежка, Вы писали:


W>>>>>>>>Легален ли следующий код:

O>>>>>>>легален, но будет летален в таком случае:
O>>>>>>>
O>>>>>>>const std::string &s = function( "foo" )
O>>>>>>>printf("s=%s\n",s.c_str());//kaboom
O>>>>>>>


С>>>>>>Не могли бы вы объяснить, чем приведенный вами код будет "летален"?

С>>>>>>Вы создаете временный неименованный объект, на который указывает константная ссылка. И пока ссулка будет жива, временный объект, на который сцществует константная сслыка, также будет жить, пока ссылка не выйдет за пределы области своей видимости.

R>>>>>Тем, что, в общем случае, у компилятора нет информации о том, что функция возвращает ссылку именно на тот объект, который был передан функции в качестве аргумента. Следовательно, и оснований для продления времени жизни этого объекта у компилятора нет. Ну разжевывали же уже эту ситуацию, даже не один раз ЕМНИП.


С>>>>Любопытно, почему у компилятора нет такой информации?! А на какой тогда по вашему объект возвращается ссылка?!


R>>>По принципу раздельной компиляции — эта функция может быть определена в другой единице трансляции. И внутреннее представление ссылок сравнить компилятор не может, потому, что во время компиляции их просто нет.


С>>Честно признаюсь, не понял, какое значение имеет раздельная компиляция? При вызове этой функции (не важно, где она определена) создается неименованный объъект, и создается ссылка на этот объект. Далее определение функции знает, что она получила ссылку и эту ссылку возвращает. То есть внутри функции никакие новые ссылки не создаются. Поэтому не вижу причем, почему раздельная компиляции как-то должна повлиять. Если бы это было так, то можно было бы сказать, что половина кода на С++ некоректные. Ведь как происходит удаление временных объектов? Компилятор смотрит, есть ли на него ссылки (не важно, сколько этих ссылок), и если нет, то удаляет объект. То же самое происходит и в этом конкретном случае. После вызова функции компилятор смотрит, есть ли ссылки на объект (а они есть, причем, как вы считаете, их может быть даже две, так как по вашему из-за раздельной компиляции компилятор не знает, что эти две ссылки одни и те же), и если есть, то объяект не удаляетася. И этот механизм не влияет на наличие раздельной компиляции.


R>Ну хорошо, давай рассмотрим пример:

R>
R>#include <string>
R>#include <iostream>

R>const std::string& foo(const std::string&);

R>int main()
R>{
R>  const std::string& text = foo("bla-bla");
R>  std::cout << text << std::endl; 
R>}
R>

R>Код вполне wel-formed и компилятор его успешно компилирует. Вопрос: по каким признакам компилятор должен понять, что временному объекту, созданному для передачи в функцию foo, нужно продлить время жизни?


Да, признаю, я глупость сморозил. Временный объект будет связан лишь с сылкой, объявленной в качестве параметра. А так как параметр функции имеет блочную область видимости, то при выходе из функции ссылка закончит свое существование, а потому и временный объект будет уничтожен.
Меня можно встретить на www.cpp.forum24.ru
Re[12]: Возвращение константной ссылки
От: c-smile Канада http://terrainformatica.com
Дата: 04.01.12 21:59
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>c-smile:


CS>>Я правильно понимаю идею что теперь (в C++11) эти двы выражения


CS>>
CS>>const std::string s1("Happy New Year");
CS>>const std::string& s2 = std::string("Happy New Year");
CS>>


CS>>эквивалентны?


M>Это не выражения, а определения, и в целом они не эквивалентны, т.к. объявляемые сущности имеют разные имена и разные declared types (которые можно получить с помощью оператора decltype). К ссылке не может применяться NRVO. Если это member-ы некоего пространства имён, имеющего внешнее связывание, то у них будет разное связывание.


Это всё понятно. Вопрос состоит в том когда будет вызван деструктор обоих строк.

В C++03 s2 есть ссылка на убитый объект — ctor и dtor в той же "строке".
В C++11 s2 есть ссылка на валидный объект — его dtor на выходе из scope.

Т.е. на самом деле ссылка может вызывать деструктор объекта на выходе из scope.
В месте объявления ссылки не всегда очевидно как эта ссылка получена.

const std::string& s1 = foo(); // foo() -> std:string
const std::string& s2 = bar(); // bar() -> const std:string&


s1 и s2 здесь явно демонстрируют разное поведение (в плане вызова деструкторов).

Несколько неожиданный side-effect на самом деле. Надо его думать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.