繁体   English   中英

了解关于 EMC++ 第 41 项的勘误表的评论

[英]Understanding comment from the errata about Item 41 of EMC++

在 Item 41 中,Scott Meyers 编写了以下两个类:

class Widget {
public:
  void addName(const std::string& newName)   // take lvalue;
  { names.push_back(newName); }              // copy it

  void addName(std::string&& newName)        // take rvalue;
  { names.push_back(std::move(newName)); }   // move it; ...

private:
  std::vector<std::string> names;
};
class Widget {
public:
  template<typename T>                            // take lvalues
  void addName(T&& newName)                       // and rvalues;
  {                                               // copy lvalues,
    names.push_back(std::forward<T>(newName)); }  // move rvalues;
  }                                               // ...
private:
  std::vector<std::string> names;
};

评论中写的是正确的,即使这并不意味着这两种解决方案是等价的,并且书中确实讨论了一些差异。

然而,在勘误表中,作者评论了书中未讨论的另一个差异:

(1) 左值和右值的重载与 (2) 采用通用引用 (uref) 的模板之间的另一个行为差异是左值重载声明了它的参数const ,而 uref 方法没有。 这意味着在左值重载的参数上调用的函数将始终是const版本,而在 uref 版本的参数上调用的函数只有在传入的参数是const时才会是const版本。 换句话说,非const左值 arguments 可能在重载设计与 uref 设计中产生不同的行为。

但我不确定我是否理解。

实际上,写这个问题我可能已经理解了,但我没有写答案,因为我仍然不确定。

可能作者是说当一个非const左值被传递给addName时, newName在第一个代码中是const ,而在第二个代码中是非const ,这意味着如果newName被传递给另一个 function (或成员 function 是调用它),而不是 function 需要采用const参数(或成为const成员函数)

我的解释是否正确?

但是,我看不出这在具体示例中有何不同,因为在newName上没有调用成员 function ,也没有将其传递给对const和非const参数具有不同重载的 function (不完全是: std::vector<T>::push_back有两个重载const T& arguments 和T&& arguments`,但左值仍然只绑定到前一个重载......)。

在第二种情况下,当将const std::string左值传递给模板时

  template<typename T>
  void addName(T&& newName)
  { names.push_back(std::forward<T>(newName)); }

实例化结果如下(我已经删除了std::forward调用,实际上,它是无操作的)

  void addName(const std::string& newName)
  { names.push_back(newName); }

而如果传递了一个std::string左值,那么addName的结果实例是

  void addName(std::string& newName)
  { names.push_back(newName); }

这意味着调用std::vector<>::push_back的非const版本

在第一种情况下,当std::string左值传递给addName时,无论const -ness如何,都会选择第一个重载

  void addName(const std::string& newName)
  { names.push_back(newName); }

这意味着在这两种情况下都选择了std::vector<>::push_backconst重载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM