Home > Back-end >  How to bind a reference to either a const param or a new object?
How to bind a reference to either a const param or a new object?

Time:12-28

Let's say I have this code:

void MyFunc(const std::string& param) {
  std::string maybe_altered_param;
  if (ConditionIsMet()) {
    maybe_altered_param = AlterParam(param);
  } else {
    maybe_altered_param = param; // <-- unnecessary copy 
  }

  // do stuff with maybe_altered_param
  // maybe_altered_param does not need to be modified further.
}

The AlterParam function returns a copy of the string, so when ConditionIsMet returns true, a copy is made in order to populate maybe_altered_param. However, a copy is made also when ConditionIsMet() returns false, which is suboptimal. In the second case I just want to have another name for the same object, without copies or anything of the sort.

What is the simplest way of removing the unnecessary copy in a case like this?

CodePudding user response:

I think your question about reference binding is misguided. It's looking for a language solution to what is essentially a code organization problem.

You want to "do stuff with maybe_altered_param", stuff you don't want to repeat for every branch (because DRY code is best code). So why not refactor that bit out?

static void MyFuncImpl(const std::string& maybe_altered_param) {
  // do stuff with maybe_altered_param
}

void MyFunc(const std::string& param) {
  if (ConditionIsMet()) {
    MyFuncImpl(AlterParam(param));
  } else {
    MyFuncImpl(param);
  }
}

Easy peasy. The extra copy is made only when the condition is met, and the stuff we do with maybe_altered_param is only spelled out once, parameterized by that parameter.

May not be the answer you are after, but I think it's worth considering.

CodePudding user response:

With extra variables, you might do:

void MyFunc(const std::string& param) {
    std::string maybe_altered_param;
    const bool condition_met = ConditionIsMet();
    if (condition_met) {
        maybe_altered_param = AlterParam(param);
    }
    const std::string& ref =
        condition_met ? maybe_altered_param : param; // both are lvalues, so no copy.
    // do stuff with ref
}
  • Related