【问题标题】:Reuse constructor. Pass rvalue to const lvalue and do not repeat implementation重用构造函数。将 rvalue 传递给 const lvalue 并且不重复实现
【发布时间】:2016-11-18 18:20:58
【问题描述】:

我知道如何简化删除重复代码。请帮助我了解它是否可用,是否良好,并可能让我们升级。

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 的额外副本?

【问题讨论】:

  • 如果您的基本情况只需要读取一个字符串(即const std::string&),那么没有理由提供其他重载。临时字符串会很好地绑定到它。
  • 为什么其中任何一个会打电话给其他人?参数数量不匹配。
  • 您对#1 的调用包括AF_INET,但#1 的签名不允许。
  • #2 和 #3 似乎调用了一些未定义的 3 参数 ''base" 类 ctor?
  • 您尝试将const std::string 绑定到std::string&&。然后离开它。大声笑

标签: c++ constructor c++14 rvalue-reference pass-by-rvalue-reference


【解决方案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 和 pre-C++11 std::string,最后一行 std::move 生成最短的汇编代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多