【问题标题】:Alternative to taking the address of a standard library function / possibly ill-formed behaviour替代获取标准库函数的地址/可能是格式错误的行为
【发布时间】:2019-07-04 10:37:24
【问题描述】:

问题:通过获取标准库函数的地址可能会导致不正确的行为...参见下面的示例。因此,我正在寻找一种替代标准库函数地址的方法。

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

【问题讨论】:

  • @JeJo 宣传我自己的问题感觉很奇怪,但确实......
  • 我不认为这是一个骗局。这不仅仅是关于是否允许获取特定std 函数的地址,而是要求解决方法,不是吗?!
  • @lubgr 是有道理的。然后相关。

标签: c++ std function-pointers unsafe


【解决方案1】:

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

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

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

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

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

还有另一种选择,您可以将函数调用包装在两个 lambda 中。这需要对原来的sn-p做一点改动:

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 都没有状态和相同的签名,所以它们隐式转换为函数指针。

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多