Повторно использовать конструктор. Передайте rvalue в const lvalue и не повторяйте реализацию

У меня есть идея, как упростить удаление повторений кода. Пожалуйста, помогите мне понять, можно ли это использовать, хорошо, и, возможно, давайте обновимся.

struct NetAdres
{
    /*#1*/NetAdres(const std::string &str, uint16_t port);  //#1
    /*#2*/NetAdres(std::string &&str, uint16_t port) : NetAdres(std::move(str), port) {};  //#2
    /*#3*/NetAdres(const char *str, uint16_t port) : NetAdres(std::string(str), port) {};  //#3
}

Этот звонок

NetAdres("192.168.2.3", 80);

насколько я понимаю звонки #3->#2->#1, И этот звонок

NetAdres(std::string("192.168.2.3"), 80);

#2->#1, Дает ли такая реализация дополнительную копию std::string?

1 ответ

Одним из возможных решений является передача по значению, например:

struct NetAddress
{
    std::string addr_;
    uint16_t port_;
    NetAddress(std::string addr, uint16_t port)
        : addr_(std::move(addr)) // <--- always involves one move
        , port_(port)
    {}
};

И затем назовите это как:

NetAddress a("example.com", 443);

// or
std::string addr("example.com");
NetAddress b(addr, 443);

// or with move
NetAddress c(std::move(addr), 443); 

Недостатком является то, что он всегда включает один std::move, которые могут или не могут быть исключены.

С g++-6.2 и до C++ 11 std::string, последняя строка с std::move генерирует самый короткий код сборки.

Другие вопросы по тегам