10

这个问题假定您熟悉P1895R0tag_invoke中介绍的定制点管理技术。

自定义点对象可以根据 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 委托给一个且唯一商定的 identifier tag_invoke,那么似乎可以通过简单地实现相同的效果,

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可以在完全不使用 Niebloid 的情况下重新实现:https ://godbolt.org/z/dzqE7b 。该代码与原始逐字记录相同,以 Niebloid 的定义为模,并对std::tag_invoke所有自定义点对象使用上述 ADL 形式。

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

4

1 回答 1

7

我不认为它tag_invoke本身是一个函数对象是绝对必要的。但是,如果我们认为有必要,将其定义为对象为我们提供了一个方便的地方来放置毒丸超载。将函数作为可以传递给高阶函数的一等公民通常很好。就是这样,真的。

于 2020-09-10T21:41:24.360 回答