为什么 tag_invoke 模式需要 Niebloid std::tag_invoke ?

2024-04-01

此问题假设您熟悉定制点管理技术tag_invoke,引入P1895R0 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf.

自定义点对象可以根据 P1895R0 定义为:

inline constexpr struct foo_cpo {
    // simplified original by omitting noexcept forward and using auto arg
    auto operator()(auto const &x) -> decltype( std::tag_invoke(*this, x) ) {
        return std::tag_invoke(*this, x); // <--^-- here are the Niebloid
    }
} foo;

但考虑到这一技术的关键是直接使用对象,并将所有 ADL 委托给一个且唯一商定的标识符tag_invoke,那么它seems可以通过简单地实现相同的效果,

inline constexpr struct {
    auto operator()(auto const &x) -> decltype( tag_invoke(*this, x) ) {
        return tag_invoke(*this, x); // no Niebloid. directly ADL call tag_invoke
    }
} foo;

例如,P1895R0 中的类型擦除示例,即https://godbolt.org/z/3TvO4f https://godbolt.org/z/3TvO4f,完全可以在不使用 Niebloid 的情况下重新实现:https://godbolt.org/z/dzqE7b https://godbolt.org/z/dzqE7b。该代码与原始逐字相同,以 Niebloid 的定义为模std::tag_invoke并对所有自定义点对象使用上述 ADL 形式。

Niebloid的存在真正满足了什么要求?tag_invoke?


我认为这并不是绝对必要的tag_invoke本身是一个函数对象。但是,如果我们认为有必要的话,将其定义为对象可以让我们方便地放置毒丸重载。通常,拥有可以传递给更高阶函数的一等公民函数是件好事。就是这样,真的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 tag_invoke 模式需要 Niebloid std::tag_invoke ? 的相关文章

随机推荐