Home > Back-end >  Does passing an std::optional<T> by reference actually save copying?
Does passing an std::optional<T> by reference actually save copying?

Time:09-22

I know that std::optional<T&> isn't supported in the standard. This question is about whether passing std::optional<T>& has any performance advantage

Sample code (https://godbolt.org/z/h56Pj6d6z) reproduced here

#include <ctime>
#include <iomanip>
#include <iostream>
#include <optional>

void DoStuff(std::optional<std::string> str) {
    if (str) std::cout << "cop: " << *str << std::endl;
}

void DoStuffRef(const std::optional<std::string>& str) {
    if (str) std::cout << "ref: " << *str << std::endl;
}

int main() {
    std::optional<std::string> str = {};
    DoStuff(str);
    DoStuffRef(str);
    str = "0123456789012345678901234567890123456789";
    DoStuff(str);
    DoStuffRef(str);
}

(My actual use case is an optional for a complex user-defined type, but I hope that a long string would do the same compiler-wise)

In this case, does DoStuffRef actually save any copying effort compared to DoStuff?

I tried to look at godbolt output but I don't know enough assembly to be sure. I do see that in the case of DoStuff, there seems to be a temp std::optional<T> created which is not present in DoStuffRef so my suspicion is that yes, passing an optional by reference save some copying

Appreciate the help!

CodePudding user response:

If you pass actual std::optional<std::string> then yes, there would be no copy. But if you pass just std::string then temporary optional has to be constructed first, resulting in a copy of the string.

CodePudding user response:

DoStuffRef saves an extra copy when argument is already std::optional<std::string> (as in your example).

But, if you pass directly a std::string, then if both cases, a std::optional should be constructed, involving copy/move constructor of the string.

  • Related