What are the coolest examples of metaprogramming that you've seen in C++?
What are some practical uses of metaprogramming that you've seen in C++?
Metaprogramming can be used to move computations from run-time to compile-time, to generate code using compile time computations, and to enable self-modifying code. The ability of a programming language to be its own metalanguage is called reflection.
Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. This means that a program can be designed to read, generate, analyze, or transform other programs, and even modify itself while running.
Generics are used for metaprogramming in Ada. They are useful for abstract algorithms that share common properties with each other.
Metaprogramming is writing programs that manipulate other programs or themselves based on metadata.
Personally, I think Boost.Spirit is a pretty amazing example of meta-programming. It's a complete parser generator that lets you express grammars using C++ syntax.
The most practical use of meta programming is turning a runtime error into a compile time error.
Example: Lets call the interface IFoo. One of my programs dealt with a COM object that had multiple paths to IFoo (very complicated inheritance hierarchy). Unfortunately the underlying COM object implementation didn't realize they had multiple paths to IFoo. They assumed it was always the left most one. So inside their code, the following pattern was very common
void SomeMethod(IFoo* pFoo) {
CFooImpl *p = (CFooImpl)pFoo;
}
The second IFoo though caused the resulting "p" pointer to be completely invalid (multiple inheritance is dangerous).
The long term solution was to have the COM object owner fix this issue. Short term though I needed to make sure that I always returned the correct IFoo. I could guarantee that I had the appropriate IFoo by using a QI and avoiding any implicit casts to IFoo. So I created a new CComPtr<> implementation and added the following override to the equal method.
template <typename T>
CComPtr<T>& operator=(const T* pT) {
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
COMPILE_ERROR();
}
This quickly revealed every single place I implicitly casted to IFoo.
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