c++ Niebloids可以在需要Callables的地方传递吗?

v1uwarro  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(95)

一般来说,除非明确允许,否则C程序获取标准库函数指针的行为是未指定的。这意味着在将它们作为 * Callable * 传递之前要格外小心。通常最好将它们 Package 在lambda中。
更多关于该主题的信息:Can I take the address of a function defined in standard library?
然而,C
20基于Range-v3 library引入了Constrained algorithms或范围算法;其中类似于函数的实体,例如std::ranges::sortstd::ranges::transform,被引入作为Niebloid。
而原始库为算法库中的每个函数创建了一个函子类,每个niebloid,如ranges::sort,只是对应函子类的一个命名对象;该标准没有具体说明应如何实施这些措施。
因此问题是,是否指定/显式允许将Niebloid作为 Callable(如std::invoke(std::ranges::sort, my_vec))传递的行为?

zujrkrfu

zujrkrfu1#

所有的规范说,在[算法.要求]是:
本条款中std​::​ranges命名空间中定义的实体未通过参数相关名称查找([basic. lookup. argdep])找到。当通过函数调用([www.example.com])中后缀表达式的非限定([basic. lookup. unqual])名称查找找到时,它们将禁止参数相关名称查找。expr.call]), they inhibit argument-dependent name lookup.
现在,实现这一点的唯一方法是使它们成为对象,但是,我们不指定这些对象的任何进一步的行为。
所以这个:

std::invoke(std::ranges::sort, my_vec)

将起作用,因为在引用它之后,它的计算结果将是std::ranges::sort(my_vec),而且没有办法真正阻止它起作用。
但是其他的用法可能就不行了,例如,std::views::transform(r, std::ranges::distance)没有被指定工作,因为我们没有说std::ranges::distance是否是可复制的--std::ranges::size是一个定制点对象,因此是可复制的,但是std::ranges::distance只是一个算法。
MSVC实现试图积极地遵守有限的规范,并且它的std::ranges::distance实现是 * 不可 * 复制的。另一方面,libstdc ++只是使它们成为空对象,因此views::transform(ranges::distance)只是通过不被主动拒绝的方式工作。
所有这些都是:一旦不再直接编写std::ranges::meow(r)(或者在usingusing namespace之后编写meow(r)),您就只能靠自己了。

相关问题