| ▲ | tialaramex 3 hours ago | |
Surely one of the obvious reasons you'd want tagged dispatch in C++ isn't obviated by either of those features? Or am I missing something? Suppose Doodads can be constructed from a Foozle either with the Foozle Resigned or with the Foozle Submitted. Using tagged dispatch we make Resigned and Submitted types and the Doodad has two specialised constructors for the two types even though substantively we pass only the Foozle in both cases. In a language like Rust all the constructors have names, it's obvious what Vec::with_capacity does while you will still see C++ programmers who thought constructing a std::vector with a single integer parameter does the same because it's just a constructor and you'd need to memorize what happens. | ||
| ▲ | quuxplusone 2 hours ago | parent | next [-] | |
I wouldn't call the idiom you describe (like with unique_lock's defer_lock_t constructor) "tag dispatch"; to me, one defining characteristic of the "tag dispatch idiom" is that the tag you're dispatching on is computed somehow (e.g. by evaluating iterator_traits<T>::iterator_category()). The idiom you're describing, I'd call simply "a constructor overload set" that happens to use the names of "disambiguation tags" to distinguish semantically different constructors because — as you point out — C++ doesn't permit us to give distinct names to the constructor functions themselves. For more on disambiguation tags, see https://quuxplusone.github.io/blog/2025/12/03/tag-types/ and https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p39... | ||
| ▲ | pjmlp 2 hours ago | parent | prev [-] | |
You use if constexpr with requires expressions, to do poor man's reflection on where to dispatch, and eventually with C++26, you do it with proper reflection support. | ||