Search code examples
c++returnpass-by-referencepass-by-value

Providing functions versions where both by value and by reference are available


I defined this function:

template <typename T>
void foo (T &result){
  //some very complicate stuff
  result = //something
}

Now, let's suppose that sometimes I want to call it with T=int and in other cases T=std::string. So, in the second case the header is efficient, but with T=int this is inefficient. Notice I'm using only these two types as an example.

So the better solution would be define another function with:

template <typename T>
T foo(){
  T result;
  //some very complicate stuff
  return result;
}

And let the user decide which version to call, but how do we avoid to call the whole code of //some very complicate stuff in the function?


Solution

  • but with T=int this is inefficient

    With compiler optimizations enabled that will very likely never matter - the cases where it matter can be detected via profiling and handled separately.


    but how do we avoid to call the whole code of //some very complicate stuff in the function?

    Well, one possible way of avoiding it would require you to pass a function object as an extra parameter:

    template <typename T, typename F>
    void foo (T &result, F&& complicated_stuff){
      std::forward<F>(complicated_stuff)();
      result = //something
    }
    

    template <typename T, typename F>
    T foo(F&& complicated_stuff){
      T result;
      std::forward<F>(complicated_stuff)();
      return result;
    }
    

    It is a good solution that will extremely likely be inlined and optimized out by the compiler... but what's the point if all you're trying to do is avoiding to pass a primitive type by reference? We're adding an extra forwarding reference here for the function object.


    Therefore, I strongly advise you to only have a single version of foo. The one that returns by value is more idiomatic C++11 and won't be slower than the one that takes a reference due to RVO and move semantics.