附錄練習題 (Practice - Appendix)


Question 1 - 右值引用與移動 [recall]

void do_stuff(X&& x_) 可以用 do_stuff(X()); 呼叫,卻不能用左值 do_stuff(x); 呼叫;而且在函式體內 X a(x_); 呼叫的竟是複製建構子。請解釋這兩個現象,並說明如何把 x_ 真正移動出去。


Question 2 - 刪除函式的兩種用途 [recall]

(1) 想讓類別不可複製、只可移動;(2) 想讓 void foo(short); 拒絕 foo(42); 這種 int 引數(避免隱式整數轉換)。分別怎麼用 =delete 達成?


Question 3 - Lambda 捕獲列表 [recall]

int i=1234, j=5678, k=9; 建立 auto f=[=,&j,&k]{return i+j+k;}; 之後執行 i=1; j=2; k=3;,此時 f() 回傳多少?若捕獲改為 [&,j,k] 又回傳多少?


Question 4 - thread_local 三類變數 [recall]

哪三類變數可以宣告為 thread_local?函式內的 thread_local 變數何時建構?程式從 main() 返回時,仍在執行的其他執行緒,其 thread_local 解構子會被呼叫嗎?


Question 5 - 參數包與 sizeof... [recall]

template<typename... Args> unsigned count_args(Args... args){ return sizeof...(Args); }sizeof... 回傳什麼?其結果可否用來指定陣列長度?另外當 Params = int, char 時,std::tuple<std::unique_ptr<Params>...> 展開成什麼?


Question 6 - 四庫對照表 [recall]

附錄 B 的四方對照中:Boost 執行緒庫與 POSIX C 在「原子操作」欄填什麼?Java 的互斥與「等待/通知」分別靠什麼機制?


Question 7 - 撰寫完美轉發包裝 [application]

請寫一個模板函式 relay,能接受任意數量、任意值類別(左值/右值)的引數並原封不動轉交給 foo;並說明為什麼不能直接寫 foo(args...)


Question 8 - 為 ATM 新增訊息 [application]

想為 ATM 加一個「列印明細」功能:使用者在選單狀態按下 p 時印出一行文字。請描述需要修改哪些地方(訊息 struct、哪個狀態的 handle 鏈、誰負責處理),框架本身需要改嗎?


Question 9 - constexpr 與初始化競爭 [analysis]

為什麼標準要求 std::mutex 的預設建構子是 constexpr?從初始化時機與競爭條件的角度分析:若它是動態初始化,會出現什麼風險?


Question 10 - dispatcher 的解構子設計 [analysis]

訊息框架讓 dispatcher / TemplateDispatcher解構子中執行 wait_and_dispatch(),並以擲出 close_queue 例外來結束迴圈。分析:為何解構子必須標 noexcept(false)?這個設計的優點與代價各是什麼?