Search code examples
c++templatesc++11generic-programmingsfinae

Why doesn't C++ make it easier to make compile time queries on types?


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.


Solution

  • 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.