首頁 >後端開發 >C++ >為什麼 C 中的「initializer_list」範本類型推導失敗?

為什麼 C 中的「initializer_list」範本類型推導失敗?

Susan Sarandon
Susan Sarandon原創
2024-12-05 01:52:09194瀏覽

Why Does Template Type Deduction Fail with `initializer_list` in C  ?

initializer_list 和模板類型推導

模板類型推導是C 的一個強大功能,它允許編譯器從傳遞給模板的參數推斷出模板的類型參數。模板。但是,在某些情況下,編譯器無法推導出類型參數,並且必須使用所需的類型參數明確實例化模板。

考慮以下函數:

template<typename T>
void printme(T&& t) {
  for (auto i : t)
    std::cout << i;
}

這個函數需要一個啟用 begin()/end() 類型的參數。問題是,為什麼下面的程式碼是非法的?

printme({'a', 'b', 'c'});

當所有這些都是合法的時:

printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});

我們甚至可以這樣寫:

const auto il = {'a', 'b', 'c'};
printme(il);

或:

printme<std::initializer_list<char>>({'a', 'b', 'c'});

或:
printme<std::vector<char>>({'a', 'b', 'c'})

第一行程式碼是非法的,因為無法推斷模板參數T。如果明確指定模板參數,它將起作用,例如:
printme<std::initializer_list<char>>({'a', 'b', 'c'})

或:

A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type.
其他程式碼行是合法的,因為參數具有明確定義的類型,因此可以很好地推導模板參數T。

可能令人困惑的部分是 auto 會選擇類型std::initializer_list;但模板參數不會。這是因為C 11 標準的§ 14.8.2.5/5 明確指出這是模板參數的非推導上下文:
if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>.
但是,對於auto,§ 7.1.6.4/6 有明確支持std: :initializer_list:

以上是為什麼 C 中的「initializer_list」範本類型推導失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn