型別推導練習題 (Practice - Deducing Types)

Question 1 - Case 1 參考參數推導 [recall]

模板宣告為 template<typename T> void f(T& param);,依序傳入 int xconst int cxconst int& rx,各呼叫的 T 與 param 型別為何?

int x = 27;
const int cx = x;
const int& rx = x;

f(x);    // T = ?  param = ?
f(cx);   // T = ?  param = ?
f(rx);   // T = ?  param = ?

Question 2 - By-Value 只剝頂層 const [recall]

const char* const ptr = "Fun with pointers"; 傳入 template<typename T> void f(T param);,T 推導為什麼型別?

Question 3 - Array 引數的 Decay [recall]

const char name[] = "J. P. Briggs";(型別 const char[13])分別傳入 by-value 模板 f(T param) 與 by-reference 模板 f(T& param),T 各是什麼?

Question 4 - Universal Reference 推導 [application]

模板為 template<typename T> void f(T&& param);,請寫出以下四個呼叫各自推導出的 T 與 param 型別。

int x = 27;
const int cx = x;
const int& rx = x;

f(x);    // T = ?  param = ?
f(cx);   // T = ?  param = ?
f(rx);   // T = ?  param = ?
f(27);   // T = ?  param = ?

Question 5 - auto 與 Braced Initializer [recall]

auto x1 = 27;auto x2(27);auto x3 = { 27 };auto x4{ 27 }; 四個宣告(依原書 C++11/14 規則)各推導出什麼型別?

Question 6 - auto 回傳型別遇上大括號 [recall]

函式 auto createInitList() { return { 1, 2, 3 }; } 能否編譯?為什麼?

Question 7 - auto&& 宣告組 [application]

已知 int x = 27; const int cx = x;,請推導 auto&& uref1 = x;auto&& uref2 = cx;auto&& uref3 = 27; 三者的型別。

Question 8 - decltype 的括號陷阱 [recall]

int x = 0; 時,decltype(x)decltype((x)) 分別是什麼型別?

Question 9 - decltype(auto) 變數宣告 [application]

Widget w; const Widget& cw = w; 之後,auto myWidget1 = cw;decltype(auto) myWidget2 = cw; 各推導出什麼型別?

Question 10 - authAndAccess 的回傳型別 [analysis]

以下 C++14 模板意圖回傳 c[i] 供呼叫端賦值,但 authAndAccess(d, 5) = 10; 卻編譯失敗——請分析原因並給出最終正確版本。

template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i)   // 有問題的版本
{
  authenticateUser();
  return c[i];
}

std::deque<int> d;
authAndAccess(d, 5) = 10;   // 編譯失敗!

Question 11 - typeid 為何不可靠 [recall]

template<typename T> void f(const T& param) 內用 typeid(param).name() 印型別,param 真正型別為 const Widget* const&,卻印出 const Widget*——為什麼?

Question 12 - 編譯期檢視型別的技巧 [recall]

不依賴任何函式庫,如何讓編譯器準確「說出」auto x = theAnswer; 推導的型別?

Question 13 - return x 與 return (x) 的天壤之別 [analysis]

兩個 decltype(auto) 函式,一個 return x;、一個 return (x);(x 為區域變數 int x = 0;)——請分析兩者回傳型別的差異與後者的嚴重後果。

decltype(auto) f1() { int x = 0; return x; }
decltype(auto) f2() { int x = 0; return (x); }