C++ references vs return values

前端 未结 4 1875
天涯浪人
天涯浪人 2021-01-12 15:34

I understand the principle point of references is to avoid making copies of large structures, but what if a function you\'re writing itself creates a large structure? Is it

相关标签:
4条回答
  • 2021-01-12 15:48

    My advice is to write the code so that the client usage is as intuitive as possible.

    If - as is usually the case - you judge that to be returning by value, then if your system is performance critical and you find a particular return value is not being optimised nicely by your compiler - even at the highest reasonable optimisation level you can use and after checking for any relevant command line options or compiler tips on achieving RVO, and considering alternative compilers if practical - ideally a C++11 compiler that benefits from always-efficient move semantics, only then change the specific problematic spot to accept the return value by reference.

    0 讨论(0)
  • 2021-01-12 15:57

    The first example should presumably be more like one of these two:

    void getLines(std::string in, std::vector<std::string> &out);
    void getLines(std::string in, std::vector<std::string> *out);
    

    The second style is often more convenient, and can in theory be made mostly as efficient as the first one:

    http://en.wikipedia.org/wiki/Return_value_optimization

    Whether this is seen in practice depends on the compiler, optimization levels, and whether the compiler can spot the opportunity in the first place.

    Whilst I don't speak for everybody, I've never actually managed to get compilers to take advantage of RVO, even with simple objects that don't do anything fancy. So I therefore personally recommend the first approach, because you are guaranteed to get the desired behaviour, on every compiler, and (which seems relevant for me...) for every programmer's code -- i.e., that the object created to hold the return value is filled in directly by the called function, without any extra copies.

    (The cost of default-constructing the result object, which is something that could potentially be avoided were RVO to be taken advantage of, is usually not significant compared to the copy the compiler might be unable to avoid.)

    Another point to note would be that if attempting to avoid unnecessary copies, passing objects by const reference instead of by value is often a good idea, e.g.:

    void getLines(const std::string &in, std::vector<std::string> &out);
    void getLines(const std::string &in, std::vector<std::string> *out);
    
    0 讨论(0)
  • 2021-01-12 16:04

    Well, in your specific case (filling a container with values) I would go for an input iterator approach. But in all other cases (like a complicated string generation or some calculations) I wouldn't care about possible performance hits and trust RVO (see Jim's answer) and the compiler to optimize it like it should. If it becomes a bottleneck (profile!), change it of course!

    0 讨论(0)
  • 2021-01-12 16:11

    That depends on if your compiler supports return value optimization (most do) and if the code qualifies for that optimization.

    0 讨论(0)
提交回复
热议问题