Является ли хорошей практикой создание оболочки вокруг функции, которая изменяет ее аргументы (выходные параметры), и мы хотим поддерживать состояние вызывающей стороны?
Есть ли лучший способ добиться этого?
Приведенный ниже пример представляет собой рекурсивную функцию, которая будет изменять свои аргументы в каждой рекурсии. Переходим по ссылке для сохранения копий. Проблема в том, что это изменит состояние вызывающего абонента, и этот побочный эффект должен быть учтен пользователем.
// Wrapper to return by value
// Example of caller
T1 data_1 = ...
T2 data_2 = ...
T3 result = foo(data_1, data_2);
T3 foo(T1 data_1, T2 data_2) // copy
{
T3 result{};
foo(data_1, data_2, result);
return result;
}
void foo(T1 &data_1, T2 &data_2, T3 &result)
{
// ...
foo(data_1.modify(), data_2.modify(), result);
}
// Alternative, out parameter by reference, will modify data_1 and data_2
// Example of caller
T1 data_1 = ...
T2 data_2 = ...
T3 result{};
foo(data_1, data_2, result);void foo(T1 &data_1, T2 &data_2, T3 &result)
{
// ...
foo(data_1.modify(), data_2.modify(), result);
}
Это нормально, и нередко, если у вас есть код, написанный перед семантикой перемещения, особенно для более старого компилятора, который может быть слаб при копировании.
Как вы говорите, это понятнее, в целом хорошо оптимизирует и экономит объявление локальных временных сообщений на сайтах вызовов.
Если у вас есть тип, который нельзя переместить или создать по умолчанию, вы все равно можете использовать старый интерфейс.
Других решений пока нет …