This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
Size
template parameters are unclearSection: 26.6.5 [alg.foreach], 26.6.15 [alg.search], 26.7.1 [alg.copy], 26.7.6 [alg.fill], 26.7.7 [alg.generate] Status: New Submitter: Jiang An Opened: 2022-10-05 Last modified: 2022-10-12
Priority: 3
View all other issues in [alg.foreach].
View all issues with New status.
Discussion:
Algorithms std::for_each_n
, std::search_n
, std::copy_n
,
std::fill_n
, and std::generate_n
have similar requirements for the
Size
template parameter in Mandates, requiring Size
to be
convertible to an integral type.
However, it is currently underspecified to which integral type Size
is
converted before further operations. There is implementation divergence:
It is also notable that when the conversion from the source type to integral types is sufficiently ambiguous, none of these implementations accepts such a source type.
For example, currently the following program is rejected by all mainstream implementations.
#include <algorithm> #include <cstdio> struct BadFrom { operator short() const { return 1; } operator unsigned short() const { return 1; } }; int main() { int arr[42]{}; std::for_each_n(arr, BadFrom{}, [&arr](int i) { std::printf("%d\n", i); }); }
I think libc++'s strategy make the most sense. But is it really intended to support using a
floating-point type or a class type as Size
?
Daniel:
The conversion from class type was indeed intended, see the original wording for LWG 3213(i), which was transferred to P1718R2.
See also LWG 3439(i) for a similar underspecified situation for template parameter
Distance
and for the underspecified Size
template parameter in
various uninitialized_*_n
and destroy_n
algorithms in
26.11.2 [special.mem.concepts].
ranges::destroy_n
has the luxury to simply require iter_difference_t<I>
.
[2022-10-12; Reflector poll]
Set priority to 3 after reflector poll.
Proposed resolution: