cppannotations/annotations/TODO
Frank B. Brokken b7d0d07263 wip
2023-08-07 11:35:23 -07:00

99 lines
3.4 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Add weak_ptr
Mention namespace chrono_literals
std::ranges
rm annotations/OBS/ entries
DONE? C++ Annotations: concepts bij 'integral' en 'floating_point' bestaat,
maar 'numeric' (of vergelijkbaar niet)
static operator()
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html
2 Motivation
The standard library has always accepted arbitrary function objects - whether
to be unary or binary predicates, or perform arbitrary operations. Function
objects with call operator templates in particular have a significant
advantage today over using overload sets since you can just pass them into
algorithms. This makes, for instance, std::less<>{} very useful.
As part of the Ranges work, more and more function objects are being added to
the standard library - the set of Customization Point Objects (CPOs). These
objects are Callable, but they dont, as a rule, have any members. They simply
exist to do what Eric Niebler termed the “Std Swap Two-Step”. Nevertheless,
the call operators of all of these types are non-static member
functions. Because all call operators have to be non-static member functions.
What this means is that if the call operator happens to not be inlined, an
extra register must be used to pass in the this pointer to the object - even
if there is no need for it whatsoever. Here is a simple example:
struct X {
bool operator()(int) const;
static bool f(int);
};
inline constexpr X x;
int count_x(std::vector<int> const& xs) {
return std::count_if(xs.begin(), xs.end(),
#ifdef STATIC
X::f
#else
x
#endif
);
}
x is a global function object that has no members that is intended to be
passed into various algorithms. But in order to work in algorithms, it needs
to have a call operator - which must be non-static: assembly code thus is
larger than required for non-static op().
Proposal:
make the call operator a static member function, instead of requiring it to
be a non-static member function.
3.1 Overload Resolution
There is one case that needs to be specially considered when it comes to
overload resolution, which did not need to be considered until now:
struct less {
static constexpr auto operator()(int i, int j) -> bool {
return i < j;
}
using P = bool(*)(int, int);
operator P() const { return operator(); }
};
static_assert(less{}(1, 2));
If we simply allow operator() to be declared static, wed have two candidates
here: the function call operator and the surrogate call function. Overload
resolution between those candidates would work as considering between:
operator()(contrived-parameter, int, int);
call-function(bool(*)(int, int), int, int);
And currently this is ambiguous because 12.2.4.1 [over.match.best.general]/1.1
stipulates that the conversion sequence for the contrived implicit object
parameter of a static member function is neither better nor worse than any
other conversion sequence. This needs to be reined in slightly such that the
conversion sequence for the contrived implicit object parameter is neither
better nor worse than any standard conversion sequence, but still better than
user-defined or ellipsis conversion sequences. Such a change would
disambiguate this case in favor of the call operator.
static operator[]:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2589r1.pdf
Stay as close as possible to the behavior of member function operator()