摘要訊息 : C++ 17 Proposal N3922《New rules for auto deduction from braced-init-list》導讀

C++ 17 Proposal N3922《New rules for auto deduction from braced-init-list》導讀

之前我曾經在文章《【C++】auto 與 decltype》中提到, 在 auto 和初始化列表下, 如果帶有指派運算子, 那麼它會被推導為 std::initializer_list 型別; 否則, 在初始化列表內有且唯有一個值的時候, 那麼變數會被推導為這個值對應的型別. 這個規則其實在 C++ 11 和 C++ 14 下是不存在的, 因為這是 N3922 為 C++ 17 帶來的內容. 我之前還在慶幸這個無意之中的發現的點, 而且還說《Effective Modern C++》的作者可能對此理解有誤, 實際上是絕對錯誤的

本來這篇文章的排程是在很久以後, 由於意識到了這個錯誤, 於是立馬就提前了

在 C++ 11 和 C++ 14 之下, auto 對於初始化列表的推導是這樣的 : 當 auto 遇見初始化列表的時候, 自動被推導為 std::initializer_list, 不論是否存在指派運算子; 其餘情況下, 正常進行推導. 也就是說在 C++ 17 之前, 實際上我們寫出

auto value {0};

auto value = {0};

的時候, value 並沒有被推導為 int 型別, 而是被推導為 std::initializer_list<int> 型別. 在 C++ 17 之後, value 才被推導為 int 型別的變數

N3922 中, 針對宣告為 auto 的初始化列表變數的型別推導作出了這樣的修正 :

  • 如果初始化列表內有且唯有一個值, 若不存在指派運算子的情況下, 那麼型別推導為那個變數對應的型別
  • 如果初始化列表內的值多於一個, 若不存在指派運算子的情況下, 那麼推導是病式的, 一般情況下是拒絕進行推導. 即 auto value {1, 2, 3, 4}; 是不可以通過編碼的

上面都是針對不存在指派運算子情況下的改動, 存在指派運算子的情況下, 還是延續了 C++ 17 之前的規則