Niebloids are colloquial of standard range algorithms that prevents undesirable Argument-dependent lookup. They prevent ADL pull-in “more specialized” std
algorithms instead of calling std::ranges::
as desired algorithm. As of C++20, the only way to implement such a “function” is to use global function object (a.k.a. customization point object).
Below is an example from the standard 1:
The entities defined in the std::ranges namespace in this Clause are not found by argument-dependent name lookup ([basic.lookup.argdep]). When found by unqualified (basic.lookup.unqual) name lookup for the postfix-expression in a function call ([expr.call]), they inhibit argument-dependent name lookup.
Example 1:
void foo() {
using namespace std::ranges;
std::vector<int> vec{1,2,3};
find(begin(vec), end(vec), 2); // #1
}
The function call expression at #1 invokes
std::ranges::find
, notstd::find
, despite that (a) the iterator type returned frombegin(vec)
andend(vec)
may be associated with namespace std and (b)std::find
is more specialized (temp.func.order) thanstd::ranges::find
since the former requires its first two parameters to have the same type. — end example]
Read More
- Customization Point Design in C++11 and Beyond by Eric Niebler
- Niebloids and Customization Point Objects by Barry Revzin