Home > Back-end >  Does modern compilers use copy elision when using the builder pattern
Does modern compilers use copy elision when using the builder pattern

Time:05-16

I am using a few builder patterns in my code base and I was wondering whether return by value should be favoured over the return by reference, given that is the push I am feeling with modern C . The example, in my opinion, would generate loads of copies if I applied the return by value approach.

class EmailBuilder
{
  public:
    EmailBuilder from(const string &from) {
        m_email.m_from = from;
        return *this;
    }
    
    EmailBuilder  to(const string &to) {
        m_email.m_to = to;
        return *this;
    }
    
    EmailBuilder  subject(const string &subject) {
        m_email.m_subject = subject;
        return *this;
    }
    
    EmailBuilder  body(const string &body) {
        m_email.m_body = body;
        return *this;
    }
    
    operator Email&&() {
        return std::move(m_email);  
    }
    
  private:
    Email m_email;
};

EmailBuilder Email::make()
{
    return EmailBuilder();
}

int main()
{
    Email mail = Email::make().from("[email protected]")
                              .to("[email protected]")
                              .subject("C   builders")
                              .body("message");
                              

}

My question is whether is if compilers would optimise the many copies generated here. As I see it, for each of the function class we generate a new copy of the builder.

CodePudding user response:

There are many cases where returning by value is favored since it typically side-steps life-time issue. This is not one of those cases because life-time of the builder is usually well defined and well understood. Thus returning by reference should be favored.

Also, in C 20 you can use designated initializers:

#include <string>

struct Email {
    std::string from    = "unknown";
    std::string to      = "unknown";
    std::string subject = "unknown";
    std::string body    = "unknown";
};

int main() {
    Email email = {
        .from   = "[email protected]",
        .to     = "[email protected]",
        .body   = "This is my email"
    };
}

(See online)

Here, subject is left "unknown".

  • Related