cpp_proposals icon indicating copy to clipboard operation
cpp_proposals copied to clipboard

P2997 - Removing the common reference requirement from the indirectly invocable concepts

Open brevzin opened this issue 2 years ago • 2 comments

P2997R0 - Removing the common reference requirement from the indirectly invocable concepts

https://github.com/cplusplus/papers/issues/1669

brevzin avatar Nov 12 '23 19:11 brevzin

This paper is making iter_common_reference_t unused in the standard library (except for range_common_reference_t which is unsed now). Implementations (libc++, libstdc++, and MSVC STL) currently don't use iter_common_reference_t in product code other than specified by the standard.

(iter_common_reference_t and range_common_reference_t are seldomly used in some test codes.)

Per search on Github, it seems that almost no one (other than implentations of ranges) uses iter_common_reference_t.


I've only found such things explaining the motivation of iter_common_reference_t/range_common_reference_t (authored by @ericniebler).

Details

P0022R2

If using a polymorphic lambda is undesirable, an alternate solution is to use the iterator’s common reference type:

// Use the iterator's common reference type to define a monomorphic relation:
using X = iter_common_reference_t<I>;
sort(first, last, [](X&& x, X&& y) {return x < y;});

Answer on stackoverflow

EDIT: The OP also asked for an example. This is a little contrived, but imagine it's C++20 and you are given a random-access range r of type R about which you know nothing, and you want to sort the range.

Further imagine that for some reason, you want to use a monomorphic comparison function, like std::less<T>. (Maybe you've type-erased the range, and you need to also type-erase the comparison function and pass it through a virtual? Again, a stretch.) What should T be in std::less<T>? For that you would use common_reference, or the helper iter_common_reference_t which is implemented in terms of it.

using CR = std::iter_common_reference_t<std::ranges::iterator_t<R>>;
std::ranges::sort(r, std::less<CR>{});

That is guaranteed to work, even if range r has proxy iterators.

And the paper P2997 itself.

But the desired pattern doesn't seem actually used (per search on Github).

Would it be better to write a new paper to deprecate/remove iter_common_reference_t?

frederick-vs-ja avatar Feb 02 '24 08:02 frederick-vs-ja

I dunno. I think it's at least theoretically useful to have, and it's cheap to provide - so I don't feel like it's problematic or anything. I mean, it's problematic in this particular case which is why we want to dumpster it... but it could be correct in other cases?

brevzin avatar Feb 02 '24 14:02 brevzin