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.

### 3793. Requirements for some algorithms' `Size` template parameters are unclear

Section: 27.6.5 [alg.foreach], 27.6.15 [alg.search], 27.7.1 [alg.copy], 27.7.6 [alg.fill], 27.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:

> - libstdc++ and libc++ use an overload set to determine the target type, and

> - MSVC STL simply chooses `std::ptrdiff_t` when `Size` is not an integral type.

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, which was transferred to P1718R2.

See also LWG 3439 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 27.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: