首页 > 解决方案 > 了解关于 EMC++ 第 41 项的勘误表的评论

问题描述

在 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左值参数可能会在重载设计与 uref 设计中产生不同的行为。

但我不确定我是否理解它。

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

可能作者是说,当一个非const左值被传递给时addName,在第一个代码中,而在第二个代码中是非-,这意味着如果被传递给另一个函数(或调用了成员函数)该函数需要接受一个参数(或者是一个成员函数)newNameconstconstnewNameconstconst

我的解释是否正确?

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

标签: c++c++11overloadingforwarding-referenceeffective-c++

解决方案


在第二种情况下,当将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); }

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

在第一种情况下,当将std::string左值传递给 时addName,将选择第一个重载,而不管const-ness

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

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


推荐阅读