1

Ich habe eine Idee, wie man Code-Wiederholungen zu vereinfachen. Bitte hilf mir zu verstehen, ob es brauchbar ist, gut und vielleicht lässt es sich upgraden.Konstruktor wiederverwenden. Übergeben Sie rvalue an const lvalue und wiederholen Sie die Implementierung nicht

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 
} 

Dieser Aufruf

NetAdres("192.168.2.3", 80); 

soweit ich Anrufe verstehen #3 ->#2 ->#1. Und dieser Aufruf

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

#2 ->#1. Gibt eine solche Implementierung keine zusätzliche Kopie von std::string?

+1

Wenn Ihr Basisfall nur das Lesen einer Zeichenfolge erfordert (d. H. "Const std :: string &'), dann gibt es keinen Grund, die anderen Überladungen bereitzustellen. Temporäre Strings binden sich gut daran. – GManNickG

+4

Warum sollte einer von denen einen der anderen anrufen? Die Anzahl der Parameter stimmt nicht überein. – aschepler

+3

Ihre Anrufe an # 1 beinhalten AF_INET, aber die Signatur von # 1 lässt dies nicht zu. – Jonas

Antwort

2

Eine mögliche Lösung ist nach Wert zu übergeben, zB:

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) 
    {} 
}; 

Und es dann gerne nennen:

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

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

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

Der Nachteil ist, dass es ist immer ein std::move, das kann oder nicht sei elide.

Mit g++-6.2 und pre-C++ 11 std::string erzeugt die letzte Zeile mit std::move den kürzesten Assemblercode.

Verwandte Themen