考慮以下程式碼:
#include <cctype> #include <functional> #include <iostream> int main() { std::invoke(std::boolalpha, std::cout); // #1 using ctype_func = int(*)(int); char c = std::invoke(static_cast<ctype_func>(std::tolower), 'A'); // #2 std::cout << c << "\n"; }
在此程式碼中,有兩次對 std::invoke 的呼叫。第 1 行取得 std::boolalpha 的位址,第 2 行嘗試對 std::tolower 執行相同操作。預期輸出是 'a'。
問題出現了:C 20 中是否能保證預期輸出?要回答這個問題,我們必須深入研究可尋址函數的概念。
根據[namespace.std],除非明確指定為可尋址,否則嘗試取得指向標準函式庫函數的指標或其引用是未定義行為(可能格式不正確)。此禁令擴展到為標準庫非靜態成員函數形成指向成員的指標。
第 1 行:
std ::boolalpha 被 [fmtflags.manip] 指定為可尋址函數。這表示取得其位址是格式正確的,相當於std::cout.setf(std::ios_base::boolalpha).
Line #2:
不幸的是,std::tolower 沒有在[cctype.syn] 中明確指定為可尋址。因此,第 2 行嘗試取得其位址的行為具有未定義的行為(可能格式錯誤)。
無法保證預期輸出。事實上,由於第 #2 行中未定義的行為,甚至無法保證程式碼能夠編譯。
此問題也適用於成員函數。如 [namespace.std] 所指出的,如果指標指向標準庫成員函數,則行為是未定義的。
以上是你能取得 C 20 中標準函式庫函數的位址嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!