考虑以下代码:
#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中文网其他相关文章!