簡體   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