6 ms·
A quick primer on type traits in modern C++
- reuben_scratton 7y agoThat was an excellent article, thank you.
- eps 7y agoalgorithm_signed() and algorithm_unsigned() in the conditional compilation example need to be templated functions for the example to make (more) sense.
- saagarjha 7y agoIs algorithm being templated not enough?
- Jaxan 7y agoTwo 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 7y ago> 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 7y agoI 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 7y agoC’s integer promotion rules aren’t the best.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- RossBencina 7y agoI 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
- jcelerier 7y ago> I found the use of 'if constexpr' in the example pretty nasty. For new code it is to be preferred - it generates less symbols than enable_if, compiles faster (by a noticeable margin from my own experience) and makes for more readable code as you don't have to go look everywhere for the various enable_if cases.
- gpderetta 7y agoEnable if is fine if you have mutually exclusive choices (although the way it work is pure magic), but it quickly becomes very complex for overlapping cases as you have to somehow hack the partial ordering in. A chain of constexpr if is significantly easier to write and understand. The right solution are of course concepts.
- skrebbel 7y agoMost of this is pretty new to me. Why is it nasty? It looks neat to me!
- RossBencina 7y agoI 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.
- rjeli 7y agoThe 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++
- jcelerier 7y agoI think that it's pretty easy if you just consider that what's happening between `template<` and `>` is a simple LISP whose values are types.
- rjeli 7y agomore like a prolog with obtuse syntax and complicated semantics
- AlexCoventry 7y agoScott Meyers' next Effective C++ is going to be a doozy. Is it even possible to usefully categorize all the edge cases anymore?
- jchb 7y agoScott Meyers has retired from C++ (his own blog post: http://scottmeyers.blogspot.com/2015/12/good-to-go.html?m=1 http://scottmeyers.blogspot.com/2015/12/good-to-go.html?m=1) so the next C++ bible has to come from somewhere else. Maybe he saw it coming :)
- Nursie 7y agoIt 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.