Re[9]: Передача параметров в функцию по указателю и по ссылк
От: σ  
Дата: 19.04.18 14:42
Оценка:
σ>>>>Зато с lvalue хуже https://wandbox.org/permlink/OH2lDAX4Qg8HdMQj

АШ>>>Дык, а почему ты включил -DCOPY_AND_SWAP?


σ>>Дык, COPY_AND_SWAP реализует идею "Когда функция эквивалентна сеттеру, то лучше передавать по значению".

σ>>Без COPY_AND_SWAP для lvalue 2 вызова вместо одного при передаче по значению.

σ>>Кстати, забыл деструктор показать. Вот, без COPY_AND_SWAP https://wandbox.org/permlink/Q422hrsrI69wPfXb


АШ>Для класса действует правило 5. Коль скоро ты определить move constructor, то, будь добр, определи и move assignment operator.


Это один из возможных вариантов. Мне больше нравится правило "четыре с половиной". Или правило 0.
Если уж мы следуем идее "Когда функция эквивалентна сеттеру, то лучше передавать по значению", то надо применять и правило "четыре с половиной" вместо правила 5.
Re[7]: Передача параметров в функцию по указателю и по ссылк
От: σ  
Дата: 19.04.18 14:55
Оценка: +1
Здравствуйте, Videoman, Вы писали:

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


G>>вот тут я сравнил оба подхода,

G>>http://cpp.sh/73t5j
G>>вы можете привести пример когда func1 выгоднее func2?

V>Зачем вы тестируете без move семантики?

V>Начиная с С++11 подход с передачей по значению, в случае с сеттером, всегда лучше, либо равен по скорости.
Это если не используется copy-and-swap идиома. С ней передача по значению начинает проигрывать для, наверное, самого распросранённого случая: передачи lvalue.
Re[8]: Передача параметров в функцию по указателю и по ссылк
От: Videoman Россия https://hts.tv/
Дата: 19.04.18 15:20
Оценка:
Здравствуйте, σ, Вы писали:

σ>Это если не используется copy-and-swap идиома. С ней передача по значению начинает проигрывать для, наверное, самого распросранённого случая: передачи lvalue.


copy-and-swap? в операторе присваивания? Как передача по значению может проигрывать, если одно копирование мы вынуждены сделать и в случае константной ссылки и в случае значения. Приведи пример.
Если ты вот такую реализацию имеешь ввиду:
B& B::operator=(B that) noexcept
{
swap(that);
return *this;
}
// против такой
B& B::operator=(const B& that)
{
B(that).swap(that);
return *this;
}

То там и там одно копирование. И там и там swap это — грубо, три move операции. Или я не понял о чем ты.
Отредактировано 19.04.2018 15:22 Videoman . Предыдущая версия .
Re[9]: Передача параметров в функцию по указателю и по ссылк
От: σ  
Дата: 19.04.18 15:33
Оценка:
Здравствуйте, Videoman, Вы писали:

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


σ>>Это если не используется copy-and-swap идиома. С ней передача по значению начинает проигрывать для, наверное, самого распросранённого случая: передачи lvalue.


V>copy-and-swap? в операторе присваивания? Как передача по значению может проигрывать, если одно копирование мы вынуждены сделать и в случае константной ссылки и в случае значения. Приведи пример.


Вот пример, с copy-and-swap (только без реализации swap) и ещё с печатью деструктором: http://cpp.sh/2ftkl
L value by value:
cctor
mctor
copy-and-swap
dtor
dtor
L value by reference:
cctor
copy-and-swap
dtor

Конечно, mctor дёшев, но это всё-таки создание-уничтожение ещё одного объекта.

V>Если ты вот такую реализацию имеешь ввиду:


Да.

V>То там и там одно копирование. И там и там swap это — грубо, три move операции. Или я не понял о чем ты.

При copy-and-swap дефолтным swap-ом через move-присваивание пользоваться нельзя, т.к. получится взаимно-рекурсивный вызов swap-ов и оператора присваивания. swap пишется свой.
Re[7]: Передача параметров в функцию по указателю и по ссылк
От: galileo Земля  
Дата: 19.04.18 17:29
Оценка:
Здравствуйте, Videoman, Вы писали:

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


G>>вот тут я сравнил оба подхода,

G>>http://cpp.sh/73t5j
G>>вы можете привести пример когда func1 выгоднее func2?

V>Зачем вы тестируете без move семантики?

V>Начиная с С++11 подход с передачей по значению, в случае с сеттером, всегда лучше, либо равен по скорости.
V>Примеры
V>Чем класс ближе к размеру ссылки, тем разница меньше. Чем класс и его операции тяжелее, чем выигрыш весомее.

выигрыш будет только в том случае если сеттер не копирует данные в себя а не явно "крадет" указатель на какие то расшареные данные через move
а в этом случае лучше просто хранить указатель, что гораздо прозрачней, и тогда да "Чем класс ближе к размеру ссылки, тем разница меньше. Чем класс и его операции тяжелее, чем выигрыш весомее."

кроме того код засоряется мувами

в общем, нет, я могу предположить что есть какие то частные случаи, когда этот подход может иметь место, но в качестве рекомендации, я бы советовал избегать такого синтаксиса
Re[10]: Передача параметров в функцию по указателю и по ссылк
От: Videoman Россия https://hts.tv/
Дата: 19.04.18 20:48
Оценка:
Здравствуйте, σ, Вы писали:

σ>Вот пример, с copy-and-swap (только без реализации swap) и ещё с печатью деструктором: http://cpp.sh/2ftkl

σ>L value by value:
σ>cctor
σ>mctor
σ>copy-and-swap
σ>dtor
σ>dtor
σ>L value by reference:
σ>cctor
σ>copy-and-swap
σ>dtor

σ>Конечно, mctor дёшев, но это всё-таки создание-уничтожение ещё одного объекта.


1. Во всех остальных случаях передача по значению выигрывает.
2. Во всех классах, которые мало-мальски выделяют память или ресурсы (а это очень часто встречается), будет быстрее.
3. Для очень маленьких классов, типа размера указателя, move и копирование ссылки не будет отличаться по скорости.
4. Move будет проигрывать только для классов на подобие больших структур, где все поля хранятся по значению. Не факт что это будет медленнее. Из-за спекулятивного выполнения и кеша, нужно будет профилировать каждую реализацию по времени.

Ну т.е. почти всегда выгоднее передавать по по значению, и только, если оптимизация покажет, что в этом месте hot-path, только в этом случае, нужно заморачиваться с ссылками или другими оптимизациями.

σ>При copy-and-swap дефолтным swap-ом через move-присваивание пользоваться нельзя, т.к. получится взаимно-рекурсивный вызов swap-ов и оператора присваивания. swap пишется свой.

Так вроде бы никто дефолтный swap использовать не предлагает .
В конечном счете, любая реализация swap сведется к рекурсивному вызову swap для всех предков и для всех полей класса, до тез пор, пока нельзя будет вызвать std::swap.
Re[2]: Передача параметров в функцию по указателю и по ссылке
От: pokutan Израиль http://pokutan.com/
Дата: 20.04.18 12:24
Оценка:
Здравствуйте, Amygdala, Вы писали:

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


A>В указателе может быть NULL, как особый вариант работы функции, или необязательный параметр. Через ссылку же передается реально существующая переменная и она обязана быть.

Ага, ща.
А как же *(MyType*)NULL?
Re[3]: Передача параметров в функцию по указателю и по ссылке
От: Amygdala Россия  
Дата: 20.04.18 12:28
Оценка:
Здравствуйте, pokutan, Вы писали:

P>Ага, ща.

P>А как же *(MyType*)NULL?

Извращаться по-разному можно. Но это возможный источник ошибок и вообще не канон.
Re[3]: Передача параметров в функцию по указателю и по ссылке
От: _NN_ www.nemerleweb.com
Дата: 20.04.18 18:55
Оценка:
Здравствуйте, pokutan, Вы писали:

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


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


A>>В указателе может быть NULL, как особый вариант работы функции, или необязательный параметр. Через ссылку же передается реально существующая переменная и она обязана быть.

P>Ага, ща.
P>А как же *(MyType*)NULL?
Разыменование нулевого указателя — неопределённое поведение.
Компилятор имеет право делать некоторые допущения, приводящие к не тому коду, который имел ввиду автор.
Например: https://www.viva64.com/ru/b/0306/
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Передача параметров в функцию по указателю и по ссылк
От: nekocoder США  
Дата: 20.04.18 21:06
Оценка:
Здравствуйте, Amygdala, Вы писали:

P>>А как же *(MyType*)NULL?


A>Извращаться по-разному можно. Но это возможный источник ошибок и вообще не канон.


А тут и извращаться не надо.
private:
IHandler* handler = nullptr;

...

invokeHandler(*handler);

Совершенно повседневная ситуация.
Отредактировано 20.04.2018 21:06 nekocoder . Предыдущая версия .
Re[5]: Передача параметров в функцию по указателю и по ссылк
От: _NN_ www.nemerleweb.com
Дата: 21.04.18 14:22
Оценка:
Здравствуйте, nekocoder, Вы писали:

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


P>>>А как же *(MyType*)NULL?


A>>Извращаться по-разному можно. Но это возможный источник ошибок и вообще не канон.


N>А тут и извращаться не надо.

N>
N>private:
N>IHandler* handler = nullptr;

N>...

N>invokeHandler(*handler);
N>

N>Совершенно повседневная ситуация.

А вы инициализируйте на нулевым указателем, а пустым значением.
IHandler* handler = empty_handler;
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.