
A quick primer on type traits in modern C++ - tblr
https://www.internalpointers.com/post/quick-primer-type-traits-modern-cpp
======
rjeli
The amount of background knowledge you need to understand what’s happening
here... I don’t envy people who have to catch up

becoming more and more convinced that when sfinae opened the Turing hatch it
doomed c++

~~~
Nursie
It just looks kinda wrong to me - If your generic template has to switch on
what type it's been passed, surely you've made it too generic somewhere?
Adding back conditional compilation or execution afterwards strikes me as the
same sort of code-smell as checking if something is an instance of a given
class before then casting it and calling a member - you've lost information
and using some sort of reflection to get it back looks like poorly thought out
code. Sure, there are times when you more or less have to, but you ought to
try to avoid them.

But what do I know, I haven't done C++ for about 5 years and was never _that_
into it.

~~~
gpderetta
You do not switch on types, you switch on groups of tuoes having certain
properties. It is not a new thing this sort of thing has been doable for the
last 20 years in a form or another.

------
reuben_scratton
That was an excellent article, thank you.

------
RossBencina
I found the use of 'if constexpr' in the example pretty nasty. I would have
thought it more idiomatic to use std::enable_if to enable different
implementations of 'algorithm' as in the example of 'construct' and 'destroy'
given here:

[https://en.cppreference.com/w/cpp/types/enable_if](https://en.cppreference.com/w/cpp/types/enable_if)

~~~
skrebbel
Most of this is pretty new to me. Why is it nasty? It looks neat to me!

~~~
RossBencina
I consider it nasty (compared to the std::enable_if example that I linked)
because it does not express the programmer's intent.

When you use enable_if to enable specific algorithm variants for specific
trait predicates, you're saying "here is the specialised algorithm to use when
this predicate is satisfied". Both the predicate and the algorithm code that
relies on the predicate being satisfied are part of the template
specialization definition. There's no chance of missing a precondition: it's
stated right in the definition. Another advantage is that it's completely
modular -- you can add or remove specializations at will.

On the other hand, the example in the post using 'if constexpr' wraps the
algorithm in an extra layer of indirection (a generic wrapper) with a bunch of
constexpr if-else spaghetti used to dispatch to the correct implementation.
Even if the if-else spaghetti is pristine, the fact remains that the predicate
and the specialized code that depends on the predicate as a precondition have
been separated out into two independent code sites.

------
eps
algorithm_signed() and algorithm_unsigned() in the conditional compilation
example need to be templated functions for the example to make (more) sense.

~~~
saagarjha
Is algorithm being templated not enough?

~~~
Jaxan
Two points. 1) Currently, the code could be written with normal overloading
(one for int and one for unsigned). No traits required. 2) The current code
relies on an implicit cast to int or unsigned int. I’m not sure that’s good.

~~~
edflsafoiewq
> Currently, the code could be written with normal overloading (one for int
> and one for unsigned). No traits required

f( (uint8_t)0 ) will dispatch to the overload f(int) with overloads. The type-
trait code will dispatch to f_unsigned(unsigned).

~~~
dirtydroog
I didn't believe you but you're right. The uint8_t gets promoted to int, not
unsigned int.

[https://godbolt.org/z/icQHw3](https://godbolt.org/z/icQHw3)

~~~
saagarjha
C’s integer promotion rules aren’t the best.

