gpt4 book ai didi

c++ - 自 C++20 以来保持或传递不可寻址的函数

转载 作者:行者123 更新时间:2023-12-01 13:37:58 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Can I take the address of a function defined in standard library?

(1 个回答)


去年关闭。




C++20 新增可寻址函数规则 16.5.4.2.1 [namespace.std]/6 :--重点是我的--

Let F denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template. Unless F is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to F. [ Note: Possible means of forming such pointers include application of the unary & operator ([expr.unary.op]), addressof ([specialized.addressof]), or a function-to-pointer standard conversion ([conv.func]). — end note ] Moreover, the behavior of a C++ program is unspecified (possibly ill-formed) if it attempts to form a reference to F or if it attempts to form a pointer-to-member designating either a standard library non-static member function ([member.functions]) or an instantiation of a standard library member function template.



据我所知,数学函数没有被规范标记为可寻址函数。

这是否意味着以下代码自 C++20 起是非法的(如 noted by cppreference 以及其他标准库函数的示例):
// unspecified and illegal?
auto func = static_cast<float (*)(float, float)>(std::pow);
std::cout << func(2, 4) << std::endl;

下面的代码呢,它合法吗?
// legal? or unspecified and illegal?
std::function<float(float, float)> f = static_cast<float(*)(float, float)>(std::pow);
std::cout << f(2, 3) << std::endl;

  • C++20 中这个新限制的原因是什么?
  • 这样的限制不是打破遗留代码吗?
  • 自 C++20 以来,保存或传递不可寻址函数的正确方法是什么?
  • 最佳答案

    这条规则来自 P0551 .这里的措辞是“未指定(可能格式错误)”——不是未定义的行为,不是格式错误的 NDR,没有类似的东西。

    现在,该库主要围绕直接使用 API 进行设计、指定和实现。库指定什么 x.foo(y, z)手段和实现必须遵循该规范。但是有很多方法可以实现这一点 - 也许 foo接受一些额外的默认参数,或者可以是一个模板,或者是一个重载集。

    此外,也许在 C++N 中,只有 x.foo(y, z) .但是在 C++N+1 中,有一个新提案添加了 x.foo(y)也。例如,在 C++03 中只有一个 vector::push_back但现在有两个。

    What is the reason for this new restriction in C++20?



    限制的原因(它在概念上并不是新的,更多的是它最终被阐明)是为了允许更改标准库。这些类型的更改只有在您获取这些函数之一的地址时才能观察到 - 基本上是图书馆说它不在乎这些更改是否破坏了您的代码,因为这是您的错,而不是委员会/图书馆的错。

    另见 Standard Library Compatibility .

    Isn't such a restriction breaking legacy code?



    并不真地。它更不喜欢这样做的代码,然后不担心将来是否有任何更改可能会破坏它。

    What is the right way since C++20 to hold or pass around non-addressable-functions?



    将它们包裹在 lambda 中。该 lambda 甚至可以是无状态的,这允许您仍然将其转换为函数指针。它仍然是一个函数指针,但它不受任何 future 标准库更改的影响。

    关于c++ - 自 C++20 以来保持或传递不可寻址的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62251497/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com