微調練習題 (Practice - Tweaks)

Question 1 - 值傳遞成本會計 [recall]

void addNamestring newName) { names.push_back(std::move(newName); } 相較於 overloading 或 universal reference 方案,傳入 lvalue 與 rvalue 各付出多少 copy/move 成本?

Question 2 - 標題四限定詞 [recall]

Item 41 的標題「Consider pass by value for copyable parameters that are cheap to move and always copied」中,四個限定詞各自防範什麼?

Question 3 - 對值參數 std::move [recall]

addNamestring newName 函式體內對 newName 呼叫 std::movestd::move 不是通常用在 rvalue reference 上嗎?為什麼這裡安全?

Question 4 - Slicing problem [recall]

void processWidget(Widget w) 其中 Widget 是 base class,傳入 SpecialWidget 物件會發生什麼事?

Question 5 - Move-only setter 設計 [application]

你要為 std::unique_ptr<std::string> 成員寫一個 setter,同事建議用值傳遞「一個函式搞定」,你該怎麼寫?為什麼?

Question 6 - Assignment 複製的成本分析 [analysis]

Password::changeTostring newPwd) { text = std::move(newPwd; } 以 lvalue 呼叫時,為何成本可能比 const std::string& overload 高出數個數量級?此成本又取決於哪些因素?

Question 7 - push_back 字面值的隱藏成本 [recall]

std::vector<std::string> vs; vs.push_back("xyzzy"); 在執行期實際發生幾次 std::string 建構與解構?emplace_back 又如何?

Question 8 - 介面本質差異 [recall]

insertion 函式與 emplacement 函式的參數在「意義」上有何根本不同?這解釋了什麼效率差異?

Question 9 - 幾乎必勝三條件 [recall]

依 Item 42 的 heuristic,哪三個條件同時成立時,emplacement 幾乎必定勝過 insertion?

Question 10 - Copy init vs direct init [recall]

std::regex r1 = nullptr; 不能編譯,std::regex r2(nullptr); 卻可以——兩種語法的官方術語是什麼?與 explicit 建構子的關係為何?

Question 11 - emplace_back(nullptr) 除錯 [application]

同事寫了 std::vector<std::regex> regexes; regexes.emplace_back(nullptr);,編譯通過但程式執行期崩潰。請解釋原因,以及為何 push_back(nullptr) 反而編不過。

Question 12 - 自訂 deleter 的容器插入 [application]

要把帶自訂 deleter 的 std::shared_ptr<Widget> 加入 std::list<std::shared_ptr<Widget>>(不能用 std::make_shared),ptrs.emplace_back(new Widget, killWidget); 有什麼問題?正確寫法為何?

Question 13 - Emplacement 不必勝的情境 [analysis]

「emplacement 理論上永不比 insertion 慢」——請以 vs.emplace(vs.begin(), "xyzzy") 與「向 std::set 加入重複值」兩個情境,分析實務上這句話為何不成立。