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

Alternative to taking the address of a standard library function / possibly ill-formed behaviour

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

根据http://eel.is/c++draft/namespace.std#6 and as noted by @Caleth in

"Note that you are relying on unspecified (possibly ill-formed) behaviour by taking the address of a standard library function (that isn't designated addressable)"

如本例所示:

int (*fun)(int) = std::toupper;
int t = fun('x');

我的问题:

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

2) static_cast 是否使指向标准库函数的函数指针安全?喜欢:

int (*fun)(int) = static_cast<int(*)(int)>(std::toupper);
int t = fun('x');

2) 是否有另一种方法可以通过带有签名 "int fun(int)"

的单个函数实现以下功能
bool choice = true;
int (*fun)(int);

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

int t = fun('x');

is there no safe way to call (in this example) toupper by pointer?

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

does a static_cast make the function pointer to a std lib function safe?

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

Is there another way to achieve the below functionality via a single function with signature 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');

这很好用,因为两个 lambda 都没有状态和相同的签名,所以它们隐式转换为函数指针。