Кто что из c++0x использует. И кто на что нарвался?
От: denisko http://sdeniskos.blogspot.com/
Дата: 06.12.11 19:00
Оценка:
Предлагаю в эту тему накидать плюсы, которые вам дало использование c++0x вместо традиционного с++ и грабли, которые он разбросал. Для создания небольшого словарика примеров того, как делать надо и как не надо.
Для нас пока прижилось lambda и auto. Грабли -- пришлось вводить требование на длину лямбы не более 10 строк, ибо если больше, то практически нечитаемо; В GCC есть мелкий баг, что она плохо инстанцирует шаблоны, если параметром его является лямбда (газенбаг), причем лямбду парсит нормально, а остальные аргументы может не разобрать, если они указаны неявно.
<Подпись удалена модератором>
Re: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 06.12.11 19:39
Оценка: 7 (2)
enum class
+ удобно — не захламляется пространство имен в котором оно объявлено; ClientResponseType::None порой куда секси и понятнее чем CRT_NONE или ClientResponseType_None
— пока ещё непривычно и порой возникают wtf при чтении; VC++ 2010 не поддерживает, IntelliSense не поддерживает

nullptr
+ приятно — по сравнению с NULL, при чтении, я сразу стал понимать что тут делается + проверка времени компиляции
— только последние ICC и GCC держат его

override
+ обалденно — то, что должно ещё быть в С++ 99 — проверка времени компиляции; читаемость++
— нет полной поддержки

&&
+ оргазм — теперь у меня по одной паре аллокация/освобождение, AddRef()/Release() вместо нескольких; производительность++
— надо уметь готовить, больше писать

auto + decltype
классно (без комментариев)
Re: Кто что из c++0x использует. И кто на что нарвался?
От: Banned by IT  
Дата: 06.12.11 23:27
Оценка:
Здравствуйте, denisko, Вы писали:

D>Предлагаю в эту тему накидать плюсы, которые вам дало использование c++0x вместо традиционного с++ и грабли, которые он разбросал.


Прижились и сильно облегчили жизнь:
auto
decltype
variadic templates
defaulted and deleted functions
rvalue references
concatenation of mixed-width string literals
static_assert

ну и мелочи там всякие типа >>, trailing comma и др.

лямбды так и не нашёл куда приткнуть чтоб с ними было лучше чем без них.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: Кто что из c++0x использует. И кто на что нарвался?
От: ArtDenis Россия  
Дата: 07.12.11 04:36
Оценка:
Здравствуйте, о_О, Вы писали:

о_О>&&

о_О>+ оргазм — теперь у меня по одной паре аллокация/освобождение, AddRef()/Release() вместо нескольких; производительность++
о_О>- надо уметь готовить, больше писать
А можно по-подробнее, а то я уже много чего из нового стандарта использую, но профита от && никак не могу понять.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: jazzer Россия Skype: enerjazzer
Дата: 07.12.11 04:57
Оценка: +1
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, о_О, Вы писали:


о_О>>&&

о_О>>+ оргазм — теперь у меня по одной паре аллокация/освобождение, AddRef()/Release() вместо нескольких; производительность++
о_О>>- надо уметь готовить, больше писать
AD>А можно по-подробнее, а то я уже много чего из нового стандарта использую, но профита от && никак не могу понять.

код становится гораздо проще.
Можно все возвращать по значению, не опасаясь за производительность.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 07.12.11 05:24
Оценка:
Здравствуйте, ArtDenis, Вы писали:

о_О>>&&

о_О>>+ оргазм — теперь у меня по одной паре аллокация/освобождение, AddRef()/Release() вместо нескольких; производительность++
о_О>>- надо уметь готовить, больше писать
AD>А можно по-подробнее, а то я уже много чего из нового стандарта использую, но профита от && никак не могу понять.

Эту штуку используют для перемещения состояний между объектами. Надеюсь я правильно выразился.

Например, через push_back(value_type&& x) можно засунуть данные объекта в контейнер без лишнего копирования. Фактически вместо копирования работают swap-алгоритмы.

Или, например, в коде
string build_string()
{
 string result;

 //... build code

 return result;
}


Можно вместо "return result;" написать "return std::move(result);" и ты будешь "перемещать" result в результат функции, а не копировать его.

----
Лично я (в основном коде) использую только эту "&&" фичу из новых возможностей C++. Да и то — только через макросы вида
//VS2010
#define __STL_MOVE_VALUE(x)      std::move(x)
#define __STL_FORWARD_VALUE(T,x) std::forward<T>(x)

//old compilers
#define __STL_MOVE_VALUE(x) (x)
#define __STL_FORWARD_VALUE(T,x) (x)

Поскольку пока все еще хочу сохранять совместимость исходного кода со "старыми" компиляторами. Типа VS2005/VS2008. Хотя сейчас 99% провожу в VS2010

----
Вот что бы я очень хотел бы юзать так это auto. Бо (накатав достаточно много кода на C# с его var) явное указание типов для переменных уже напрягает.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 06:41
Оценка: +2
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Или, например, в коде

КД>
КД>string build_string()
КД>{
КД> string result;

КД> //... build code

КД> return result;
КД>}
КД>


КД>Можно вместо "return result;" написать "return std::move(result);" и ты будешь "перемещать" result в результат функции, а не копировать его.

имхо это пример, как неправильно использовать move
return result; <-- достаточно без всяких move
компилятор сообразит, что лучше сделать
это все равно, что советовать кругом вставлять слово inline
Re[5]: Кто что из c++0x использует. И кто на что нарвался?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 07.12.11 06:47
Оценка:
Здравствуйте, uzhas, Вы писали:

U>имхо это пример, как неправильно использовать move

U>return result; <-- достаточно без всяких move
U>компилятор сообразит, что лучше сделать
U>это все равно, что советовать кругом вставлять слово inline

Возможно, но я по-моему тестировал — компилятор VS2010 не рюхал и ему надо было подсказывать
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 07:03
Оценка:
Здравствуйте, denisko, Вы писали:

D>Предлагаю в эту тему накидать плюсы, которые вам дало использование c++0x вместо традиционного с++ и грабли, которые он разбросал. Для создания небольшого словарика примеров того, как делать надо и как не надо.

используем &&

грабли в &&
1) люди начинают их впихивать туда, где передача по значению была бы приемлемой (тут можете меня поучить)
пример:
//class B is movable
class A
{
public:
  //я чего-то не понимаю или тут реально не нужно && ? ведь это ненужное ограничение на клиента
  void SetB(B&& b)
  {
    m_b = std::move(b);
  }

  B m_b;
};


2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator= (тут тоже можете меня поучить)
//variant 1
class A
{
public:
  A& operator=(A&& other)
  {
    CloseResource();
    std::swap(m_Resource, other.m_Resource);
    return *this;
  }

  ~A()
  {
    CloseResource();
  }

private:
  ResourceType m_Resource;
};

//variant 2
class A
{
public:
  A& operator=(A&& other)
  {
    std::swap(m_Resource, other.m_Resource);
  }

  ~A()
  {
    //free resource
  }
private:
  ResourceType m_Resource;
};

//variant 3
class A
{
public:
  A& operator=(A&& other)
  {
    A tmp(std::move(other));
    std::swap(tmp.m_Resource, m_Resource);
    return *this;
  }

private:
  ResourceType m_Resource;
};

приходится внимательно следить за состоянием other =\
в студии 2010 достаточно бедная поддержка =\
Re[6]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 07:06
Оценка: 34 (5)
Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>Возможно, но я по-моему тестировал — компилятор VS2010 не рюхал и ему надо было подсказывать

пока еще глупый компилятор, значит
вот кстати интересная статья на тему rvalue&& http://thbecker.net/articles/rvalue_references/section_01.html
Re[2]: Кто что из c++0x использует. И кто на что нарвался?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 07.12.11 07:09
Оценка: +2
Здравствуйте, uzhas, Вы писали:

U>грабли в &&

U>1) люди начинают их впихивать туда, где передача по значению была бы приемлемой (тут можете меня поучить)
U>пример:
//class B is movable
class A
{
 public:
  //я чего-то не понимаю или тут реально не нужно && ? ведь это ненужное ограничение на клиента
  void SetB(B&& b)
  {
    m_b = std::move(b);
  }

  B m_b;
};


Лично я определяю SetB(B&& b) только в довесок к нормальному "void SetB(const B& b)"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 07:16
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Лично я определяю SetB(B&& b) только в довесок к нормальному "void SetB(const B& b)"

а для чего это надо? почему нельзя было обойтись одним методом, принимающим аргумент по значению?
void SetB(B b);
я могу себе еще такое представить, когда два метода определяются в шаблонных классах, ибо они могут работать как с movable, так и не с movable классами (хотя тут тоже есть о чем кумекать)
Re[4]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 07.12.11 07:27
Оценка: 4 (1)
Коваленко Дмитрий:

КД>Или, например, в коде

КД>
КД>string build_string()
КД>{
КД> string result;

КД> //... build code

КД> return result;
КД>}
КД>


КД>Можно вместо "return result;" написать "return std::move(result);" и ты будешь "перемещать" result в результат функции, а не копировать его.


Такая замена только исключит возможность применения RVO. В отношении return действуют особые правила:

12.8/32:

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. —end note ]

[ Example:

class Thing {
public:
  Thing();
  ~Thing();
  Thing(Thing&&);
private:
  Thing(const Thing&);
};

Thing f(bool b) {
  Thing t;
  if (b)
    throw t;         // OK: Thing(Thing&&) used (or elided) to throw t
  return t;          // OK: Thing(Thing&&) used (or elided) to return t
}

Thing t2 = f(false); // OK: Thing(Thing&&) used (or elided) to construct t2

—end example ]

Re[4]: Кто что из c++0x использует. И кто на что нарвался?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 07.12.11 07:29
Оценка:
Здравствуйте, uzhas, Вы писали:

КД>>Лично я определяю SetB(B&& b) только в довесок к нормальному "void SetB(const B& b)"

U>а для чего это надо? почему нельзя было обойтись одним методом, принимающим аргумент по значению?
U>void SetB(B b);
Я хотел написать, что "только с появлением && стал понятен очень древний совет — передавать аргументы по значению. типа компилятор там сам разберется". Но потом передумал

Да потому что если код будет собираться старым компилятором, то
void SetB(B b)
{
 m_std_vector_of_B.push_back(b);
}

будет хуже чем
void SetB(const B& b)
{
 m_std_vector_of_B.push_back(b);
}
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 07:34
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>Я хотел написать, что "только с появлением && стал понятен очень древний совет — передавать аргументы по значению. типа компилятор там сам разберется". Но потом передумал

это свежий совет
древний совет — передавайте все по ссылке
хочется разобраться когда применять свежий совет, а когда нет

КД>Да потому что если код будет собираться старым компилятором, то

все же меня интересуют именно новые возможности, хочется в них разобраться
Re[6]: Кто что из c++0x использует. И кто на что нарвался?
От: LaptevVV Россия  
Дата: 07.12.11 07:40
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Коваленко Дмитрий, Вы писали:



КД>>Я хотел написать, что "только с появлением && стал понятен очень древний совет — передавать аргументы по значению. типа компилятор там сам разберется". Но потом передумал

U>это свежий совет
U>древний совет — передавайте все по ссылке
U>хочется разобраться когда применять свежий совет, а когда нет
Атомарные данные — по значению. Агрегаты — по ссылке.
Типа Капитан Очевидность.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 07:49
Оценка: :))) :)
Здравствуйте, LaptevVV, Вы писали:

LVV>Атомарные данные — по значению. Агрегаты — по ссылке.

LVV>Типа Капитан Очевидность.
больше похоже на Капитан Невтеме
Re[2]: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 07.12.11 08:37
Оценка:
Здравствуйте, uzhas, Вы писали:

U>грабли в &&

U>1) люди начинают их впихивать туда, где передача по значению была бы приемлемой
U>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator= (тут тоже можете меня поучить)

это потому что люди не умеют готовить &&. в частности не понимают разницы std::forward/std::move и как их использовать, и вообще "что там происходит"

что там происходит — http://rsdn.ru/forum/cpp/3731204.1.aspx
Автор: Masterkent
Дата: 11.03.10

как использовать std::forward/std::move — http://gcc.gnu.org/ml/libstdc++/2007-08/msg00037.html
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 08:41
Оценка:
Здравствуйте, о_О, Вы писали:

о_О>это потому что люди не умеют готовить &&. в частности не понимают разницы std::forward/std::move и как их использовать, и вообще "что там происходит"

научите готовить
более-менее конкретные примеры я описал выше, как по-вашему "правильно" их написать?
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 08:43
Оценка:
Здравствуйте, о_О, Вы писали:


о_О>что там происходит — http://rsdn.ru/forum/cpp/3731204.1.aspx
Автор: Masterkent
Дата: 11.03.10

о_О>как использовать std::forward/std::move — http://gcc.gnu.org/ml/libstdc++/2007-08/msg00037.html
это все о шаблонах, для моих примеров неактуально
Re[4]: Кто что из c++0x использует. И кто на что нарвался?
От: jazzer Россия Skype: enerjazzer
Дата: 07.12.11 08:55
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>>Лично я определяю SetB(B&& b) только в довесок к нормальному "void SetB(const B& b)"

U>а для чего это надо? почему нельзя было обойтись одним методом, принимающим аргумент по значению?
U>void SetB(B b);
U>я могу себе еще такое представить, когда два метода определяются в шаблонных классах, ибо они могут работать как с movable, так и не с movable классами (хотя тут тоже есть о чем кумекать)

Потому что представь, что твой В — это тяжелый std::vector.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 09:03
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Потому что представь, что твой В — это тяжелый std::vector.

ну прямо под землю провалимся от его веса
если клиент захочет отдать объект, он передаст владение через вызов SetB(std::move(b));
если не захочет — то передаст копию SetB(b);
Re[4]: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 07.12.11 09:33
Оценка:
Здравствуйте, uzhas, Вы писали:

U>научите готовить


сомневаюсь что моё дилетантское мнение кому-то интересно, но тем не менее:

U>1) люди начинают их впихивать туда, где передача по значению была бы приемлемой (тут можете меня поучить)

class A
{
public:
  //я чего-то не понимаю или тут реально не нужно && ? ведь это ненужное ограничение на клиента
  void SetB(B&& b)
  {
    m_b = std::move(b);
  }

  B m_b;
};


т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам. что касается случая с передачей по значению, то тут лучше вообще не использовать ни замещение ни дополнение:
void SetB(const B& b);
void SetB(B&& b); //добавили. OK

//...

void SetB(B b); //удалили
void SetB(B&& b); //добавили. WRONG -- весь клиентский код переписывать

void SetB(B b);
void SetB(B&& b); //добавили. WRONG -- возможны неоднозначности


U>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator=


т.к. мы можем принять временный объект, а можем переместить один объект в другой, реализация A::operator=(B&& b) должна быть следующей:
 - освобождение ресурсов A
 - перемещение ресурсов B в A

а вот как вы это реализуете, уже не имеет значения. смысл лишь в том, чтобы объект A был чист перед перемещением, а объект B после перемещения.
Re[6]: Кто что из c++0x использует. И кто на что нарвался?
От: jazzer Россия Skype: enerjazzer
Дата: 07.12.11 09:41
Оценка:
Здравствуйте, uzhas, Вы писали:

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


J>>Потому что представь, что твой В — это тяжелый std::vector.

U>ну прямо под землю провалимся от его веса
U>если клиент захочет отдать объект, он передаст владение через вызов SetB(std::move(b));
U>если не захочет — то передаст копию SetB(b);

Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой
Обычно предпочитают делать на вызываемой, чтоб облегчить клиентский код, чтоб клиенту не надо было все время писать std::move (более того, тебе его тоже придется написать, когда будешь присваивать).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 09:47
Оценка:
Здравствуйте, о_О, Вы писали:

о_О>т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам.

возможно, вас сбило слово "впихивать", поэтому вы подсчитали, что что-то наращивается
представим, что класс A пишется с нуля
какую сигнатуру для SetB вы порекомендуете?


U>>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator=


о_О>т.к. мы можем принять временный объект, а можем переместить один объект в другой, реализация A::operator=(B&& b) должна быть следующей:

о_О>
о_О> - освобождение ресурсов A
о_О> - перемещение ресурсов B в A
о_О>

о_О>а вот как вы это реализуете, уже не имеет значения. смысл лишь в том, чтобы объект A был чист перед перемещением, а объект B после перемещения.
ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )
из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3
если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще
если бы std::move не превращал нормальные объекты во "временные", то можно было бы делать банальный swap (variant 2), а так как новый стандарт разрешает корежить\портить нормальные объекты, то приходится изголяться, как в variant 3, что неблаготворно сказывается на качестве кода
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 10:01
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой

казалось бы палка о двух концах, но я так не считаю
напомню о чем я говорю, чтобы мы говорили об одном и том же:
SetB(B&&) с точки зрения дизайна вносит необоснованное ограничение (невозможность подставить lvalue) ради некоторой оптимизации
SetB(B b) не имеет такого ограничения и тоже позволяет применить оптимизацию
так вот:
1) не все вектора тяжелые
2) класс чаще всего может работать как я тяжелыми так и с легкими векторами, как следствие, решение тяжелый вектор или нет вполне логично принять на клиентской стороне
3) нет такой best-practice передавать владения векторов, вектор как тип нетяжелый, тяжелым он может быть лишь в некоторых случаях в рантайме

J>Обычно предпочитают делать на вызываемой, чтоб облегчить клиентский код, чтоб клиенту не надо было все время писать std::move (более того, тебе его тоже придется написать, когда будешь присваивать).

в реальности облегчения скорее всего не будет, т.к. клиенту все равно надо будет писать std::move, если у него lvalue
весь вопрос в том, должен ли его заставить это сделать метод SetB или же предоставить клиенту выбор
если выбора нет, то передать копию клиенту придется так:
B b;
SetB(B(b));
//work with b

Re[6]: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 07.12.11 10:19
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, о_О, Вы писали:


о_О>>т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам.

U>возможно, вас сбило слово "впихивать", поэтому вы подсчитали, что что-то наращивается
U>представим, что класс A пишется с нуля
U>какую сигнатуру для SetB вы порекомендуете?

по значению

U>>>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator=


о_О>>т.к. мы можем принять временный объект, а можем переместить один объект в другой, реализация A::operator=(B&& b) должна быть следующей:

о_О>>
о_О>> - освобождение ресурсов A
о_О>> - перемещение ресурсов B в A
о_О>>

о_О>>а вот как вы это реализуете, уже не имеет значения. смысл лишь в том, чтобы объект A был чист перед перемещением, а объект B после перемещения.
U>ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )

почему?)

U>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3


вариант 2 вообще неверен, остались 1 и 3.

U>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще


у GCC вариант 1

U>если бы std::move не превращал нормальные объекты во "временные", то можно было бы делать банальный swap (variant 2), а так как новый стандарт разрешает корежить\портить нормальные объекты, то приходится изголяться, как в variant 3, что неблаготворно сказывается на качестве кода


для простых типов возможен только вариант 1. итого 2 разные реализации == ни есть гут

и вообще. у vc++ 3й, у gcc 1й; у меня, 1й у вас 3й -- быдлан какой-то
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 07.12.11 11:00
Оценка:
Здравствуйте, о_О, Вы писали:

U>>какую сигнатуру для SetB вы порекомендуете?


о_О>по значению


вот и у меня такое же мнение

U>>ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )


о_О>почему?)


да напрягает как-то освобождать сви ресурсы
вместо того, чтобы всю деструктивную логику держать в деструкторе, мне приходится делать функцию CloseAll() и вызывать ее из деструктора и из operator=(A&&)
U>>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3

о_О>вариант 2 вообще неверен, остались 1 и 3.

виноват, забыл return, основная идея этого варианта в банальном swap-е

U>>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще


о_О>у GCC вариант 1

опачки, это интересно

о_О>и вообще. у vc++ 3й, у gcc 1й; у меня, 1й у вас 3й -- быдлан какой-то

я был бы рад, если бы вариант 2 был приемлем )) уж очень он простой )))
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 07.12.11 11:29
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, о_О, Вы писали:


U>>>какую сигнатуру для SetB вы порекомендуете?


о_О>>по значению


U>вот и у меня такое же мнение


всё верно. и вы уже сами объяснили почему

U>>>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3

о_О>>вариант 2 вообще неверен, остались 1 и 3.
U>виноват, забыл return, основная идея этого варианта в банальном swap-е
я и не заметил про return
я когда в свой умный указатель для COM объедков прикручивал && вначале так и написал — swap(). потом подумал и понял, что fail. далее я долго маялся — как же делать — вариант 1 или 3. т.к. я помешан на читаемости кода, решил что 1

U>>>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще


о_О>>у GCC вариант 1

U>опачки, это интересно
stl в vs 2010 кривая. вон у shared_ptr нельзя явно инстанцировать экземпляр, т.к. они вместо _Swap написали swap
вот тут если не ошибаюсь:
  void swap(_Myt&& _Right)
  {    // exchange contents with movable _Right
    _Mybase::_Swap(_STD move(_Right));
  }
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 08.12.11 11:23
Оценка:
о_О:

о_О>вариант 2 вообще неверен, остались 1 и 3.


Вариант 2 вполне может быть верным, тут всё зависит от требований к состоянию moved from объекта в каждом конкретном случае.

Ну и неплохо было бы напомнить о существовании 4-го варианта:

A &operator=(A &&) noexcept = default;

Добиться, чтобы это сработало, во многих случаях не так уж и сложно. Заодно не нужно будет думать о реализации функции swap (std::swap вполне хватит).
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
От: о_О
Дата: 08.12.11 12:42
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Ну и неплохо было бы напомнить о существовании 4-го варианта:


M>
A &operator=(A &&) noexcept = default;

M>Добиться, чтобы это сработало, во многих случаях не так уж и сложно. Заодно не нужно будет думать о реализации функции swap (std::swap вполне хватит).

каюсь, про defaulted, deleted ещё не читал
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 08.12.11 12:49
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Ну и неплохо было бы напомнить о существовании 4-го варианта:


M>
A &operator=(A &&) noexcept = default;

а как нам стандарт обещает реализовать этот оператор? среди моих трех вариантов есть "стандартный" ?
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
От: SleepyDrago Украина  
Дата: 08.12.11 13:32
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>о_О:


о_О>>вариант 2 вообще неверен, остались 1 и 3.


M>Вариант 2 вполне может быть верным, тут всё зависит от требований к состоянию moved from объекта в каждом конкретном случае.


M>Ну и неплохо было бы напомнить о существовании 4-го варианта:


M>
A &operator=(A &&) noexcept = default;

M>Добиться, чтобы это сработало, во многих случаях не так уж и сложно. Заодно не нужно будет думать о реализации функции swap (std::swap вполне хватит).

можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат. Можно просто ссылки на код, можно на группы/обсуждения. Хоть что нибудь, пожалуйста.

зы я обеими ногами за #include <thread> и все что с ним связано, но пока выглядит этот новый язык как мутный головняк.
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 08.12.11 14:32
Оценка:
uzhas:

M>>Ну и неплохо было бы напомнить о существовании 4-го варианта:


M>>
A &operator=(A &&) noexcept = default;


U>а как нам стандарт обещает реализовать этот оператор?


Через почленный move. См. 12.8/28.

U>среди моих трех вариантов есть "стандартный" ?


Я не понял вопрос.
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 08.12.11 14:33
Оценка:
Про rvalue references можно почитать в FAQ от Страуструпа (пройти по ссылочкам, приведённым в FAQ, также не помешает).
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: Banned by IT  
Дата: 08.12.11 20:06
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат. Можно просто ссылки на код, можно на группы/обсуждения. Хоть что нибудь, пожалуйста.


Да вот хотя бы примитивный тест:

1М элементов
sort для vector<string> — 1.852954 sec, дофигища копирований
sort для vector<string>, string c поддержкой move constructor/operator — 0.532721 sec, ни одного копирования
Разница в 3.478280 раза
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: jazzer Россия Skype: enerjazzer
Дата: 09.12.11 07:48
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат.


Там все просто.
В С++03 при присваивании или инициализации из временного объекта происходит сначала копирование всего содержимого объекта в новый, а потом разрушение временного. std::vector, например — нужно выделить память, скопировать все объекты, которые можуг быть тяжелыми сами по себе, хотя достаточно было всего лишь перекинуть указатель на буфер и обойтись вообще без выделений и копирований.
В С++11 ссылки на rvalue позволяют явно прописать, как именно перемещать содержимое из временного объекта, и компилятор будет этим способом по возможности пользоваться.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: Кто что из c++0x использует. И кто на что нарвался?
От: Sir-G  
Дата: 09.12.11 07:51
Оценка:
Здравствуйте, Banned by IT, Вы писали:

BBI>1М элементов

BBI>sort для vector<string> — 1.852954 sec, дофигища копирований
BBI>sort для vector<string>, string c поддержкой move constructor/operator — 0.532721 sec, ни одного копирования
BBI>Разница в 3.478280 раза
Я может че не понимаю... Если нужна производительность сортировки массива, то
1) можно хранить указатели на объекты (в данном случае строк).
2) делать эффективный swap элементов массива, который можно реализовать и в рамках C++03.
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
От: jazzer Россия Skype: enerjazzer
Дата: 09.12.11 07:51
Оценка: +1
Здравствуйте, uzhas, Вы писали:

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


J>>Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой

U>казалось бы палка о двух концах, но я так не считаю
U>напомню о чем я говорю, чтобы мы говорили об одном и том же:
U>SetB(B&&) с точки зрения дизайна вносит необоснованное ограничение (невозможность подставить lvalue) ради некоторой оптимизации
U>SetB(B b) не имеет такого ограничения и тоже позволяет применить оптимизацию

Это ложный выбор. Правильно объявлять оба варианта: SetB(B&&) для случаев, когда аргумент — временный объект, и SetB(const B&) — для случаев, когда объект нормальный долгоживущий.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Кто что из c++0x использует. И кто на что нарвался?
От: neFormal Россия  
Дата: 09.12.11 08:02
Оценка:
Здравствуйте, Banned by IT, Вы писали:

BBI>variadic templates


а можно примеров их удобного использования? пока встречал только всякую плохочитабельную содомию..
хотя у меня был ровно один случай, где они бы пригодились..
...coding for chaos...
Re[3]: Кто что из c++0x использует. И кто на что нарвался?
От: Banned by IT  
Дата: 09.12.11 10:12
Оценка:
Здравствуйте, neFormal, Вы писали:

BBI>>variadic templates


F>а можно примеров их удобного использования? пока встречал только всякую плохочитабельную содомию..

F>хотя у меня был ровно один случай, где они бы пригодились..

У меня тоже ровно один случай: typesafe аналог CString::Format. Раньше там была уличная магия через operator comma.

Вариадики — штука специфическая, реальная необходимость в них есть только вот таких вот случаях: когда надо передать в функцию неизвестное колво параметров и разных типов.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[11]: Кто что из c++0x использует. И кто на что нарвался?
От: Banned by IT  
Дата: 09.12.11 10:12
Оценка:
Здравствуйте, Sir-G, Вы писали:

BBI>>1М элементов

BBI>>sort для vector<string> — 1.852954 sec, дофигища копирований
BBI>>sort для vector<string>, string c поддержкой move constructor/operator — 0.532721 sec, ни одного копирования
BBI>>Разница в 3.478280 раза
SG>Я может че не понимаю... Если нужна производительность сортировки массива, то
Это всего лишь был наглядный пример. Есеснно этого достичь можно разными путями. Но && введено в стандарт именно для уменьшения объёмов рукопашки.
Кроме сортировки также просто ускоряется к примеру всякий container.push_back (Object (param, param, ...)); и прочие места где объект обычно передаётся как rvalue.

SG>1) можно хранить указатели на объекты (в данном случае строк).

Можно. Но с && можно хранить сами объекты, что сильно удобнее в использовании, и тем не менее тот же vector resize будет происходить в разы быстрее.

SG>2) делать эффективный swap элементов массива, который можно реализовать и в рамках C++03.

Можно. Но тогда надо переписать тонну стандартных алгоритмов чтоб они умели использовать специальный swap для твоего типа и стандартный swap для всех остальных?

А так у тебя есть где то в глубине:
template <class T> std::move (T& a, T& b)
{
    T c = std::move (a);
    a = std::move (b);
    b = std::move (c);
}


Который в зависимости от того имеет класс move constructor/operator= или нет работает либо через copy либо через move. Сам, автоматически.
В этом и есть смысл.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[11]: Кто что из c++0x использует. И кто на что нарвался?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 09.12.11 11:07
Оценка:
Здравствуйте, Sir-G, Вы писали:

SG>Я может че не понимаю... Если нужна производительность сортировки массива, то

SG>1) можно хранить указатели на объекты (в данном случае строк).
SG>2) делать эффективный swap элементов массива, который можно реализовать и в рамках C++03.

STL из VS2010 при перепаковке вектора использует swap, а тот использует move-операции.

Так что лучше сразу определить свой вариант swap.

Если я все правильно попутал
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: enji  
Дата: 09.12.11 13:12
Оценка:
Здравствуйте, jazzer, Вы писали:


J>Это ложный выбор. Правильно объявлять оба варианта: SetB(B&&) для случаев, когда аргумент — временный объект, и SetB(const B&) — для случаев, когда объект нормальный долгоживущий.


Ну setB — ладно. А предположим есть функция с тремя аргументами — это что, 8 перегрузок получается?
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 09.12.11 13:44
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Правильно объявлять оба варианта: SetB(B&&) для случаев, когда аргумент — временный объект, и SetB(const B&) — для случаев, когда объект нормальный долгоживущий.

чем это лучше одного метода SetB(B b) ?
я вижу лишь усложнение, а где же профит? экономия на стеке?
Re[10]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 10.12.11 10:09
Оценка:
uzhas:

J>>Правильно объявлять оба варианта: SetB(B&&) для случаев, когда аргумент — временный объект, и SetB(const B&) — для случаев, когда объект нормальный долгоживущий.

U>чем это лучше одного метода SetB(B b) ?
U>я вижу лишь усложнение, а где же профит? экономия на стеке?

Если имеется в виду сравнение

class A
{
public:
    void SetB(B const &b)
    {
        m_b = b;
    }
    void SetB(B &&b)
    {
        m_b = std::move(b);
    }
    // ...
private:
    B m_b;
};

с

class A
{
public:
    void SetB(B b)
    {
        m_b = std::move(b);
    }
    // ...
private:
    B m_b;
};

то во втором варианте получается на одну move-операцию больше (в некоторых случаях она быть устранена в соответствии с 12.8/31/3). Если такая дополнительная move-операция не напрягает, то передача по значению сгодится. Напомню, что перемещение не всегда дешёвое — нередко оно сводится к копированию.
Re[11]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 10.12.11 10:28
Оценка:
Masterkent:

M>то во втором варианте получается на одну move-операцию больше


Тут, конечно, ещё надо учитывать особенности реализации присваивания у B. Скажем, для

struct B
{
    // ...
    B(B const &x);
    B(B &&x);

    B &operator =(B const &x)
    {
        return *this = B(x);
    }
    B &operator =(B &&x);
};

при передаче в SetB lvalue типа B или const B разницы не будет.
Re[11]: Кто что из c++0x использует. И кто на что нарвался?
От: uzhas Ниоткуда  
Дата: 10.12.11 12:41
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Если имеется в виду сравнение

да, речь об этих вариантах
но мы немного уже запутали друг друга))
моя позиция следующая
//class B is movable
class A1
{
  B m_b;
public:
  void SetB(B b)
  {
    m_b = std::move(b);
  }
};

class A2
{
  B m_b;
public:
  void SetB(const B& b)
  {
    m_b = b;
  }

  void SetB(B&& b)
  {
    m_b = std::move(b);
  }
};

class A3
{
  B m_b;
public:
  void SetB(B&& b)
  {
    m_b = std::move(b);
  }
};


из предложенных трех вариантов на практике с точки зрения дизайна в подавляющем кол-ве случаев самым лучшим является вариант A1:
в A2 я вижу дубликацию логики (профит может быть в слишком специфических случаях, когда двойной move в A1 плохо сказывается на перформансе)
в A3 я вижу необоснованное ограничение "отдай мне владение", об этом я писал выше
то есть передавайте по значению — это хорошее полезное правило для легко movable сущностей, что-то типа best practice
Re[12]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 10.12.11 17:15
Оценка:
uzhas:

U>из предложенных трех вариантов на практике с точки зрения дизайна в подавляющем кол-ве случаев самым лучшим является вариант A1:


Насчёт подавляющего количества случаев — х.з. Но вариант годный.

U>в A2 я вижу дубликацию логики


Не такая уж страшная дубликация получается, IMHO. Тоже годный вариант.

U>в A3 я вижу необоснованное ограничение "отдай мне владение"


Такое будет хорошо только для non-copyable B.
Re[12]: Кто что из c++0x использует. И кто на что нарвался?
От: Masterkent  
Дата: 11.12.11 15:23
Оценка:
Masterkent:

M>Тут, конечно, ещё надо учитывать особенности реализации присваивания у B. Скажем, для


M>
struct B
M>{
M>    // ...
M>    B(B const &x);
M>    B(B &&x);

M>    B &operator =(B const &x)
M>    {
M>        return *this = B(x);
M>    }
M>    B &operator =(B &&x);
M>};

Вот же ж склероз — в который раз уже забыл noexcept у move-операций проставить.

struct B
{
    // ...
    B(B const &x);
    B(B &&x) noexcept; // или хотя бы throw()

    B &operator =(B const &x)
    {
        return *this = B(x);
    }
    B &operator =(B &&x) noexcept; // или хотя бы throw()
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.