Два способа возврата результата для одного действия
От: unhelper  
Дата: 06.10.12 21:37
Оценка:
Некоторые действия можно выполнить двумя способами: изменить передаваемый аргумент или вернуть результат в виде отдельного значения. Типичный пример — операторы += и +. Обычно первый записывает результат в левый операнд, а второй возвращает временное значение. Мне понадобилось определить несколько вспомогательных функций для работы со строками, и тут я столкнулся с аналогичной ситуацией. Например, функцию удаления замыкающих пробельных символов можно реализовать в двух вариантах

// пишем результат в аргумент и возвращаем ссылку на аргумент
string& remove_trailing_whitespaces(string& s);

// возвращаем результат в виде временного объекта
string remove_trailing_whitespaces(const string& s);

Хотелось бы иметь сразу оба варианта, но я пока не могу сообразить, как бы их получше совместить. Такая перегрузка меня не устраивает, так как легко будет допустить ошибку. Можно дать функциям разные названия, но какие? Коверкать названия приписыванием какой-нибудь невнятной абракадабры не хочется. Приставки или суффиксы, если уж их использовать, должны быть достаточно информативными, но не слишком длинными. Ничего подходящего я придумать не смог Может, в Boost или других библиотеках есть примеры разруливания такой ситуации?
Re: Два способа возврата результата для одного действия
От: -MyXa- Россия  
Дата: 06.10.12 22:04
Оценка: 3 (2)
Здравствуйте, unhelper, Вы писали:

Например, _copy, как здесь
Если не поможет, будем действовать током... 600 Вольт (C)
Re: Два способа возврата результата для одного действия
От: Centaur Россия  
Дата: 07.10.12 06:52
Оценка:
Здравствуйте, unhelper, Вы писали:

U>Некоторые действия можно выполнить двумя способами: изменить передаваемый аргумент или вернуть результат в виде отдельного значения. Типичный пример — операторы += и +. Обычно первый записывает результат в левый операнд, а второй возвращает временное значение. Мне понадобилось определить несколько вспомогательных функций для работы со строками, и тут я столкнулся с аналогичной ситуацией.


Стандартная библиотека C++ использует схему именования verb и verb_copy.

В Python’е есть функции sort (сортирующая массив на месте и не возвращающая ничего) и sorted (возвращающая сортированную копию исходного массива).

В некоторых случаях можно и вовсе определять только чистую функцию или только деструктивную.
Re: Два способа возврата результата для одного действия
От: Аноним  
Дата: 07.10.12 10:29
Оценка:
Здравствуйте, unhelper, Вы писали:

void remove_trailing_whitespaces(string& s);

string remove_trailing_whitespaces(const string& s);
Re: Два способа возврата результата для одного действия
От: Кодт Россия  
Дата: 07.10.12 16:18
Оценка:
Здравствуйте, unhelper, Вы писали:

U>Хотелось бы иметь сразу оба варианта, но я пока не могу сообразить, как бы их получше совместить.


Вопрос именно в названии, или в том, как реализовать без дублирования кода?

Если в названии, — то, конечно, надо оглядываться на уже сложившуюся в твоём проекте практику. Если такой ещё нет, то предлагаю
— remove_trailing_spaces_inplace / remove_trailing_spaces

Если в реализации, то
— с преждевременной пессимизацией, — выразить одну функцию через другую, и затем дошлифовывать производительность по мере нужды
— написать промежуточную функцию, например, на итераторах, которую можно натравить на begin(src),end(src),back_inserter(dst) либо begin(src),end(src),begin(src).
Перекуём баги на фичи!
Re[2]: Два способа возврата результата для одного действия
От: jazzer Россия Skype: enerjazzer
Дата: 08.10.12 05:45
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Стандартная библиотека C++ использует схему именования verb и verb_copy.


C>В Python’е есть функции sort (сортирующая массив на месте и не возвращающая ничего) и sorted (возвращающая сортированную копию исходного массива).


В Boost.Range такое же именование, только там вместо копии ленивые view:
http://www.boost.org/libs/range/doc/html/range/reference/adaptors/reference.html
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: Два способа возврата результата для одного действия
От: Roman Odaisky Украина  
Дата: 12.10.12 10:41
Оценка:
Здравствуйте, unhelper, Вы писали:

U>Можно дать функциям разные названия, но какие?


trim(s1);
s3 = trimmed(s2);

Или rtrim. Или strip/rstrip/lstrip, это всё более-менее общепринятые имена, если речь именно об удалении пробельных символов.
До последнего не верил в пирамиду Лебедева.
Re: Два способа возврата результата для одного действия
От: B0FEE664  
Дата: 12.10.12 11:04
Оценка:
Здравствуйте, unhelper, Вы писали:

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


U>
// пишем результат в аргумент и возвращаем ссылку на аргумент
U>string& remove_trailing_whitespaces(string& s);

U>// возвращаем результат в виде временного объекта
U>string remove_trailing_whitespaces(const string& s);


Я бы ожидал использование библиотечных функций в данном случае.
Например:
здесь:

    string str1="     hello world!     ";
    string str2=trim_left_copy(str1);   // str2 == "hello world!     "
    string str3=trim_right_copy(str1);  // str3 == "     hello world!"
    trim(str1);                         // str1 == "hello world!"

    string phone="00423333444";
    // remove leading 0 from the phone number
    trim_left_if(phone,is_any_of("0")); // phone == "423333444"


U>Может, в Boost или других библиотеках есть примеры разруливания такой ситуации?

Boost использует суффикс _copy, но не всегда следует смотреть на boost. Важнее принятый для конкретного проекта стиль именования и кодирования.
И каждый день — без права на ошибку...
Re[2]: Два способа возврата результата для одного действия
От: B0FEE664  
Дата: 12.10.12 11:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>void remove_trailing_whitespaces(string& s);
А>


Это не удобно. Часто хочется написать нечто, вроде:
 if ( 0 == remove_trailing_whitespaces(strName).size() )
   return;
И каждый день — без права на ошибку...
Re[3]: Два способа возврата результата для одного действия
От: Аноним  
Дата: 12.10.12 11:50
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Это не удобно. Часто хочется написать нечто, вроде:

BFE>
BFE> if ( 0 == remove_trailing_whitespaces(strName).size() )
BFE>   return;
BFE>


Весьма плохо иметь в подобном выражении побочный эффект, это чреватое трудноуловимыми ошибками объединение двух операций в одну.

Это, кстати, нарушение базового принципа Command-Query Separation.
Re[4]: Два способа возврата результата для одного действия
От: B0FEE664  
Дата: 12.10.12 13:42
Оценка:
Здравствуйте, Аноним, Вы писали:

BFE>>Это не удобно. Часто хочется написать нечто, вроде:

BFE>>
BFE>> if ( 0 == remove_trailing_whitespaces(strName).size() )
BFE>>   return;
BFE>>


А>Весьма плохо иметь в подобном выражении побочный эффект, это чреватое трудноуловимыми ошибками объединение двух операций в одну.

Ни разу за свою многолетнюю практику я не сталкивался с трудноуловимыми ошибками такого рода.

Обычно трудноуловимые ошибки сводятся к чему-то такому:
assert(boost::filesystem::exists( "foo" ) == boost::filesystem::exists( "foo" ));
т.е. к ошибкам многопоточности.

А>Это, кстати, нарушение базового принципа Command-Query Separation.

if ( 0 == remove_trailing_whitespaces(remove_trailing_whitespaces(strName)).size()  )
   return;

И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.