Open StephanTLavavej opened 5 years ago
In #491, I noticed that C++17 default_searcher
is using tag dispatch when it could use if constexpr
:
https://github.com/microsoft/STL/blob/ff947563da6511270d8b7292e162f8549df8267f/stl/inc/functional#L1662-L1664
_Lex_compare_memcmp_classify
to our attention:This overload set could be if constexpr
-ed to good effect, doubly so after #1433 adds more overloads to the set.
I don't think it deserves separate issue, rather an expansion of this issue scope.
Some specializations can be replaced with if constexpr
.
Compare internal _Invoke_ret
dispached by SFINAE-selected partial specialization:
https://github.com/microsoft/STL/blob/88332706f49d3297b200b5605ef174fc47d38d1a/stl/inc/functional#L658-L685
And standard invoke_r
dispatched by if constexpr
:
https://github.com/microsoft/STL/blob/88332706f49d3297b200b5605ef174fc47d38d1a/stl/inc/functional#L33-L42
https://github.com/microsoft/STL/issues/189#issuecomment-631298439:
In #491, I noticed that C++17
default_searcher
is using tag dispatch when it could useif constexpr
:
This was addressed by #2219
https://github.com/microsoft/STL/issues/189#issuecomment-738499686:
1433 brought
_Lex_compare_memcmp_classify
to our attention:This overload set could be
if constexpr
-ed to good effect, doubly so after #1433 adds more overloads to the set.
This was addressed by #2158
There's _Seed
in <random>
:
basic_string_view
and basic_string
's find_first_of
, with the remaining functions being:find_last_of
find_first_not_of
find_last_not_of
Dispatching on iterator strength:
vector::_Insert_range()
(changed by #1794)
https://github.com/microsoft/STL/blob/f099e9c9f91187376e85385b135ac62ef933e54f/stl/inc/vector#L1027-L1166vector::_Assign_range()
(changed by #1794)
https://github.com/microsoft/STL/blob/f099e9c9f91187376e85385b135ac62ef933e54f/stl/inc/vector#L1236-L1315vector<bool>::_Insert()
(fixed by #2694)
https://github.com/microsoft/STL/blob/f099e9c9f91187376e85385b135ac62ef933e54f/stl/inc/vector#L3089-L3104There are candidates in <format>
but not sure if it worth to untag dispatch them.
Tag dispatch is the STL's original metaprogramming technique: overload a helper function on a tag struct (e.g.
input_iterator_tag
versusforward_iterator_tag
, ortrue_type
versusfalse_type
) and then call it with a tag object to select the appropriate overload. This has several downsides, though - it is somewhat verbose, it interferes with code organization, and it results in actual function calls in debug mode. (This is slower, more work to step through when debugging, and bloats object files.) C++17if constexpr
supersedes tag dispatch in almost every situation (see note below) and we're using it in new C++17-and-later code. We can use it in C++14 mode too (compilers support it unconditionally with a warning that we've suppressed).We should finish overhauling the STL to use
if constexpr
.Note: Tag dispatch works with delegating constructors, whereas
if constexpr
works only in function bodies.subrange
's delegating constructors are a rare example of necessary tag dispatch: https://github.com/microsoft/STL/blob/f099e9c9f91187376e85385b135ac62ef933e54f/stl/inc/xutility#L3345-L3356