-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Tag dispatch is the STL's original metaprogramming technique: overload a helper function on a tag struct (e.g. input_iterator_tag
versus forward_iterator_tag
, or true_type
versus false_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++17 if 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:
Lines 3345 to 3356 in f099e9c
template <class _Rng> | |
constexpr subrange(true_type, _Rng&& _Val) | |
: subrange(_STD forward<_Rng>(_Val), static_cast<_Size_type>(_RANGES size(_Val))) { | |
// delegation target for subrange(_Rng&&) when we must store the range size | |
_STL_INTERNAL_STATIC_ASSERT(_Store_size); | |
} | |
template <class _Rng> | |
constexpr subrange(false_type, _Rng&& _Val) : subrange(_RANGES begin(_Val), _RANGES end(_Val)) { | |
// delegation target for subrange(_Rng&&) when we need not store the range size | |
_STL_INTERNAL_STATIC_ASSERT(!_Store_size); | |
} |