I'm just beginning to learn template metaprogramming tricks that allow you to query about a type.
For example, SFINAE allows us to check if a type has a particular typedef or function at compile time by using overloading and return type sizeof comparisons.
Q: So, why doesn't (correct me if there are better ways in C++11/14) the language provide better mechanisms/interfaces to make these queries regarding a type?
Edit: I'd like to clarify that this isn't a rant (I'm sorry if it sounds that way). Since I'm only beginning to appreciate the power of templates, I want to ensure my thought process isn't messed up.
For each template class/function for which I want to make these queries, I'd have to create a SFINAE specific version. Wouldn't a single interface that asks the compiler "does T have a member called A
" or "does T have a function <return type> (arg list)
" be a cleaner way? Surely the compiler has all the knowledge associated with user defined types - it just needs to expose this to the programmer for compile time queries.
Q : Is relying on this general functionality a bad way of designing/thinking about templates? Please state your reasons (with examples that accomplish the task w/o querying, if possible) if that's the case.
Templates are not free to instantiate. Instantiating many templates, or templates with more code than necessary increases compiled code size and build time.
The short answer is no. Indirectly, however, they can slow things down under a few circumstances. In particular, each instantiation of a template (normally) produces code that's separate and unique from other instantiations.
All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!
Template metaprogramming, SFINAE tricks & co. weren't actually designed to do this stuff. Template metaprogramming in C++ was moslty discovered.
Templates started just as means to write type-generic code, more capabilities were added to cover corner cases (SFINAE was born to avoid compiler errors that could happen when unrelated templates were pulled in the same program), then some day someone discovered that the C++ templates provided a Turing-complete metalanguage that allowed to perform queries about types, carry out computations at compile time and the like.
So, template metaprogramming in C++ is ugly to understand, ugly to write, ugly to debug, tragic to compile because it's mostly an abuse of stuff that was intended for other usages. Templates just happened to be so powerful, but none actually designed them for this.
C++11 provides some library support to this usage (and some core language support as well), but that doesn't change the essence of the situation.
Also, if you want my opinion, template metaprogramming is currently heavily abused; with it you can build monstrosities like Boost.Spirit, but you probably shouldn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With