替代采用标准库函数的地址/可能格式不正确的行为

时间:2019-07-04 10:37:24

标签: c++ std function-pointers unsafe

问题:采用标准库函数的地址,可能是形式不正确的行为...请参见以下示例。因此,我正在寻找一种替代标准库函数地址的方法。

根据http://eel.is/c++draft/namespace.std#6并由{Caleth在Why function-pointer assignment work in direct assignment but not in conditional operator中指出

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

如本例所示:

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

我的问题:

1)没有安全的方法可以通过指针调用(在此示例中)toupper吗?

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

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');

1 个答案:

答案 0 :(得分:4)

  

没有安全的方法可以通过指针调用(在此示例中)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');

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