获取标准库函数地址的替代方法/可能是格式错误的行为

ㄈㄟㄈ*_*ㄟㄈㄟ 3 c++ unsafe function-pointers std

问题:通过获取标准库函数的地址可能会出现格式错误的行为……请参见下面的示例。因此,我正在寻找一种替代标准库函数地址的方法。

根据http://eel.is/c++draft/namespace.std#6和@Caleth 在Why function-pointer assignment work in direct assignment 但不在条件运算符中指出

“请注意,您通过获取标准库函数的地址(未指定可寻址)来依赖未指定(可能格式错误)的行为”

如本例所示:

int (*fun)(int) = std::toupper;
int t = fun('x');
Run Code Online (Sandbox Code Playgroud)

我的问题:

1) 有没有安全的方法通过指针调用(在本例中)toupper?

2) static_cast 是否使指向 std lib 函数的函数指针安全?喜欢:

int (*fun)(int) = static_cast<int(*)(int)>(std::toupper);
int t = fun('x');
Run Code Online (Sandbox Code Playgroud)

2)是否有另一种方法可以通过带有签名“int fun(int)”的单个函数来实现以下功能

bool choice = true;
int (*fun)(int);

if (choice) {
    fun = std::toupper;
}
else {
    fun = std::tolower;
}

int t = fun('x');
Run Code Online (Sandbox Code Playgroud)

lub*_*bgr 5

有没有安全的方法来通过指针调用(在这个例子中)toupper?

不是直接的,只能通过一级间接(见下文)。

是否static_cast使指向 std lib 函数的函数指针安全?

不。它可以确定一个重载设置为一个特定的函数签名,但这与是否允许获取该函数的地址没有任何关系。

是否有另一种方法可以通过带有签名的单个函数来实现以下功能 int fun(int)

还有一种替代方法,您可以将函数调用包装在两个 lambda 表达式中。这几乎不需要对原始代码段进行更改:

bool choice = true;
int (*fun)(int);

if (choice)
    fun = [](int ch){ return std::toupper(ch); };
else
    fun = [](int ch){ return std::tolower(ch); };

int t = fun('x');
Run Code Online (Sandbox Code Playgroud)

这很有效,因为两个 lambda 表达式都没有状态和相同的签名,因此它们隐式转换为函数指针。