Date: Sat, 3 Oct 2020 14:05:39 +0100
@Jason I think you mixed something up there. std::count_until means `Count
the elements until the given predicate returns true`, which is correct. And
we already have the same semantics in std::is_sorted_until btw:
https://en.cppreference.com/w/cpp/algorithm/is_sorted_until
For completeness sake, I would like to amend the implementation to this
now, which "fixes" the return type and gets rid of the magic value:
template<class InputIt, class UnaryPredicate>
typename iterator_traits<InputIt>::difference_type count_until(InputIt
first, InputIt last, UnaryPredicate pred)
{
typename iterator_traits<InputIt>::difference_type i = 0;
while (first != last)
{
if (pred(*first))
{
return i;
}
++first;
++i;
}
return i;
}
If there are no matches it returns the size of the container and if it's
the first element that matches it returns 0 which is semantically correct
with the wording I provided above.
I named the variable in the example index instead of count because that's
what the follow-up code uses it for. The function doesn't (and shouldn't)
care what you use the return value for. All it does (and should do) is what
the description says it's doing, counting the elements until X (exclusive)
is true, nothing more. It doesn't say "Use my return value as an
index". Name it countUntilX if you want to, I prefer index.
The standard library includes plenty of things that the majority of C++
programmers have never heard of and I am confident you can catch anybody
out by digging through cppreference. So we shouldn't impose hard "Not going
to be used in a majority of C++ code" limits to filter what goes into
the standard. It also doesn't mean we are bad at C++ for not knowing parts
of it. They are there to help you in case you need them, like a utility
belt. Doing an index based indirection is not a strange concept, doesn't
matter if the containers involved are vectors, lists or something entirely
different. And having a direct answer for it in the standard, whether
that's for DDD or the example I posted doesn't matter. How about simply
dumping the index to a console for quick debug purposes? Is that "real"
enough?
Lastly, legacy codebases are stuck with index-based APIs and internals. If
you own the codebase then you can refactor that to iterators. But you are
going to have a hard time convincing everyone to change this out of nowhere
in a large, commercial environment. What you can do is start encouraging
people to use this template as a bridge instead of writing new for loops
and occasionally refactoring existing function bodies with it. Over time,
you will squash the amount of code to refactor to get iterators in
place, and the final switch will be much closer to replacing the
count_until instances with find_if, it gets you halfway there, great!
That's a much easier sales pitch than "I want to replace all indices with
iterators now because it's better on paper". These codebases are real and
extending a branch to bridge this gap to modern C++ is not a bad thing. I
think we all know how difficult this can be and having something in your
toolkit to do that is a welcome addition to me.
I hope we can close out the discussion about whether or not this would be
used anywhere now.
On Sat, 3 Oct 2020 at 12:21, Simon Kraemer via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> My fault.
> I missed that part.
>
> Giuseppe D'Angelo via Std-Proposals <std-proposals_at_[hidden]>
> schrieb am Sa., 3. Okt. 2020, 12:52:
>
>> Il 03/10/20 11:42, Simon Kraemer via Std-Proposals ha scritto:
>> > > auto i = /* insert std_find_if + distance or the proposed template
>> to
>> > search in bigDynamicList. */
>> > > someLUT[i] = 42;
>> >
>> > Why not just use iterators as they are meant to be used?
>> >
>> > auto iter = std::find(...);
>> > *iter = 42;
>> >
>> > Same number of lines, no duplicate lookup.
>>
>> The example uses two different containers. You find the index in one
>> container, and use it to index in the second. How do you use iterators
>> to do the same?
>>
>> Thanks,
>>
>> --
>> Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer
>> KDAB (France) S.A.S., a KDAB Group company
>> Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
>> KDAB - The Qt, C++ and OpenGL Experts
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
the elements until the given predicate returns true`, which is correct. And
we already have the same semantics in std::is_sorted_until btw:
https://en.cppreference.com/w/cpp/algorithm/is_sorted_until
For completeness sake, I would like to amend the implementation to this
now, which "fixes" the return type and gets rid of the magic value:
template<class InputIt, class UnaryPredicate>
typename iterator_traits<InputIt>::difference_type count_until(InputIt
first, InputIt last, UnaryPredicate pred)
{
typename iterator_traits<InputIt>::difference_type i = 0;
while (first != last)
{
if (pred(*first))
{
return i;
}
++first;
++i;
}
return i;
}
If there are no matches it returns the size of the container and if it's
the first element that matches it returns 0 which is semantically correct
with the wording I provided above.
I named the variable in the example index instead of count because that's
what the follow-up code uses it for. The function doesn't (and shouldn't)
care what you use the return value for. All it does (and should do) is what
the description says it's doing, counting the elements until X (exclusive)
is true, nothing more. It doesn't say "Use my return value as an
index". Name it countUntilX if you want to, I prefer index.
The standard library includes plenty of things that the majority of C++
programmers have never heard of and I am confident you can catch anybody
out by digging through cppreference. So we shouldn't impose hard "Not going
to be used in a majority of C++ code" limits to filter what goes into
the standard. It also doesn't mean we are bad at C++ for not knowing parts
of it. They are there to help you in case you need them, like a utility
belt. Doing an index based indirection is not a strange concept, doesn't
matter if the containers involved are vectors, lists or something entirely
different. And having a direct answer for it in the standard, whether
that's for DDD or the example I posted doesn't matter. How about simply
dumping the index to a console for quick debug purposes? Is that "real"
enough?
Lastly, legacy codebases are stuck with index-based APIs and internals. If
you own the codebase then you can refactor that to iterators. But you are
going to have a hard time convincing everyone to change this out of nowhere
in a large, commercial environment. What you can do is start encouraging
people to use this template as a bridge instead of writing new for loops
and occasionally refactoring existing function bodies with it. Over time,
you will squash the amount of code to refactor to get iterators in
place, and the final switch will be much closer to replacing the
count_until instances with find_if, it gets you halfway there, great!
That's a much easier sales pitch than "I want to replace all indices with
iterators now because it's better on paper". These codebases are real and
extending a branch to bridge this gap to modern C++ is not a bad thing. I
think we all know how difficult this can be and having something in your
toolkit to do that is a welcome addition to me.
I hope we can close out the discussion about whether or not this would be
used anywhere now.
On Sat, 3 Oct 2020 at 12:21, Simon Kraemer via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> My fault.
> I missed that part.
>
> Giuseppe D'Angelo via Std-Proposals <std-proposals_at_[hidden]>
> schrieb am Sa., 3. Okt. 2020, 12:52:
>
>> Il 03/10/20 11:42, Simon Kraemer via Std-Proposals ha scritto:
>> > > auto i = /* insert std_find_if + distance or the proposed template
>> to
>> > search in bigDynamicList. */
>> > > someLUT[i] = 42;
>> >
>> > Why not just use iterators as they are meant to be used?
>> >
>> > auto iter = std::find(...);
>> > *iter = 42;
>> >
>> > Same number of lines, no duplicate lookup.
>>
>> The example uses two different containers. You find the index in one
>> container, and use it to index in the second. How do you use iterators
>> to do the same?
>>
>> Thanks,
>>
>> --
>> Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer
>> KDAB (France) S.A.S., a KDAB Group company
>> Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
>> KDAB - The Qt, C++ and OpenGL Experts
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2020-10-03 08:05:53