C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond

Category: Programming
Author: David Abrahams, Aleksey Gurtovoy
3.0
All Stack Overflow 16
This Year Stack Overflow 1
This Month Stack Overflow 2

Comments

by anonymous   2019-07-21

Unfortunately, you are mixing the concepts of compile-time and runtime programming.

In the Template Metaprogramming world, you would use something like enable_if (http://en.cppreference.com/w/cpp/types/enable_if) to accomplish what you want.

In that page there are numerous examples that will illustrate how you can select which implementation to execute at runtime, based on your compile-time types.

I would also suggest reading Dave Abraham's book on MPL (http://www.amazon.com/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255).

Once you understand MPL, you will be able to develop highly optimized programs.

by litb   2017-08-20

Beginner

Introductory, no previous programming experience

Introductory, with previous programming experience

* Not to be confused with C++ Primer Plus (Stephen Prata), with a significantly less favorable review.

Best practices


Intermediate


Advanced


Reference Style - All Levels

C++11/14 References:

  • The C++ Standard (INCITS/ISO/IEC 14882-2011) This, of course, is the final arbiter of all that is or isn't C++. Be aware, however, that it is intended purely as a reference for experienced users willing to devote considerable time and effort to its understanding. As usual, the first release was quite expensive ($300+ US), but it has now been released in electronic form for $60US.

  • The C++14 standard is available, but seemingly not in an economical form – directly from the ISO it costs 198 Swiss Francs (about $200 US). For most people, the final draft before standardization is more than adequate (and free). Many will prefer an even newer draft, documenting new features that are likely to be included in C++17.

  • Overview of the New C++ (C++11/14) (PDF only) (Scott Meyers) (updated for C++1y/C++14) These are the presentation materials (slides and some lecture notes) of a three-day training course offered by Scott Meyers, who's a highly respected author on C++. Even though the list of items is short, the quality is high.

  • The C++ Core Guidelines (C++11/14/17/…) (edited by Bjarne Stroustrup and Herb Sutter) is an evolving online document consisting of a set of guidelines for using modern C++ well. The guidelines are focused on relatively higher-level issues, such as interfaces, resource management, memory management and concurrency affecting application architecture and library design. The project was announced at CppCon'15 by Bjarne Stroustrup and others and welcomes contributions from the community. Most guidelines are supplemented with a rationale and examples as well as discussions of possible tool support. Many rules are designed specifically to be automatically checkable by static analysis tools.

  • The C++ Super-FAQ (Marshall Cline, Bjarne Stroustrup and others) is an effort by the Standard C++ Foundation to unify the C++ FAQs previously maintained individually by Marshall Cline and Bjarne Stroustrup and also incorporating new contributions. The items mostly address issues at an intermediate level and are often written with a humorous tone. Not all items might be fully up to date with the latest edition of the C++ standard yet.

  • cppreference.com (C++03/11/14/17/…) (initiated by Nate Kohl) is a wiki that summarizes the basic core-language features and has extensive documentation of the C++ standard library. The documentation is very precise but is easier to read than the official standard document and provides better navigation due to its wiki nature. The project documents all versions of the C++ standard and the site allows filtering the display for a specific version. The project was presented by Nate Kohl at CppCon'14.


Classics / Older

Note: Some information contained within these books may not be up-to-date or no longer considered best practice.

by anonymous   2017-08-20

The thing to keep in mind here is templates are different from language features like generics in languages like C#.

It is a fairly safe simplification to think of templates as an advanced preprocessor that is type aware. This is the idea behind Template metaprogramming (TMP) which is basically compile time programming.

Much like the preprocessor templates are expanded and the result goes through all of the same optimization stages as your normal logic.

Here is an example of rewritting your logic in a style more consistent with TMP. This uses function specialization.

template<bool X>
double foo(double x);

template<>
double foo<true>(double x)
{
    return moo(x);
}

template<>
double foo<false>(double x)
{
    return bar(x);
}

TMP was actually discovered as a happy accident and is pretty much the bread and butter of the STL and Boost.

It is turing complete so you can do all sorts of computation at compile time.

It is lazily evaluated so you could implement your own compile time asserts by putting invalid logic in a specialization of a template that you don't want to be used. For example if I were to comment out the foo<false> specialization and tried to use it like foo<false>(1.0); the compiler would complain, although it would be perfectly happy with foo<true>(1.0);.

Here is another Stack Overflow post that demonstrates this.

Further reading if interested:

  1. Modern C++ Design
  2. C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond
  3. Effective C++
by anonymous   2017-08-20

The classic book C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond comes with a 20 page appendix on profiling compile-time costs. It has a companion CD with the code that generates the graphs in that appendix.

Another paper is http://aszt.inf.elte.hu/~gsd/s/cikkek/profiling/profile.pdf, perhaps that is of use to you.

Yet another, but more labor-intensive, way is to count the number of instantiations of each class from your compiler output.

by anonymous   2017-08-20

Templates are a very powerful mechanism which can simplify many things. However to use them properly requires much time and experience - in order to decide when their usage is appropriate.

For me the most important advantages are:

  • reducing the repetition of code (generic containers, algorithms)
  • reducing the repetition of code advanced (MPL and Fusion)
  • static polymorphism (=performance) and other compile time calculations
  • policy based design (flexibility, reusability, easier changes, etc)
  • increasing safety at no cost (i.e. dimension analysis via Boost Units, static assertions, concept checks)
  • functional programming (Phoenix), lazy evaluation, expression templates (we can create Domain-specific embedded languages in C++, we have great Proto library, we have Blitz++)
  • other less spectacular tools and tricks used in everyday life:
    • STL and the algorithms (what's the difference between for and for_each)
    • bind, lambda (or Phoenix) ( write clearer code, simplify things)
    • Boost Function (makes writing callbacks easier)
    • tuples (how to genericly hash a tuple? Use Fusion for example...)
    • TBB (parallel_for and other STL like algorithms and containers)
  • Can you imagine C++ without templates? Yes I can, in the early times you couldn't use them because of compiler limitations.
  • Would you write in C++ without templates? No, as I would lose many of the advantages mentioned above.

Downsides:

  • Compilation time (for example throw in Sprit, Phoenix, MPL and some Fusion and you can go for a coffee)
  • People who can use and understand templates are not that common (and these people are useful)
  • People who think that they can use and understand templates are quite common (and these people are dangerous, as they can make a hell out of your code. However most of them after some education/mentoring will join the group mentioned in the previous point)
  • template export support (lack of)
  • error messages could be less cryptic (after some learning you can find what you need, but still...)

I highly recommend the following books:

by anonymous   2017-08-20

I don't understand why people here post things about WinAPI, .NET, MFC and ATL.

You really must know the language. Another benefit would be the cross platform libraries. C++ is not about GUI or Win32 programming. You can write Multi-Platform application with libraries like boost, QT, wxWidgets (may be some XML parser libs).

Visual C++ is a great IDE to develop C++ application and Microsoft is trying hard to make Visual C++ more standard conform. Learning standard language without dialects (MS dialect as well) will give you an advantage of Rapid Development Environment combined with multi-platform portability. There are many abstraction libraries out there, which work equally on Windows, Linux, Unix or Mac OS. Debugger is a great app in VC++ but not the first thing to start with. Try to write unit tests for your application. They will ensure on next modifications that you did not broke other part of tested (or may be debugged:) code.

Do not try to learn MFC or ATL from scratch, try to understand STL. MFC is old, and new version are more or less wrapper around ATL. ATL is some strange lib, which tries to marry STL-idioms (and sometimes STL itself) and WinAPI. But using ATL concepts without knowing what is behind, will make you unproductive as well. Some ATL idioms are very questionable and might be replaced by some better from boost or libs alike.

The most important things to learn are the language philosophy and concepts. I suggest you to dive into the language and read some serious books:

When here you will be a very advanced C++ developer Next books will make guru out of you:

Remember one important rule: If you have a question, try to find an answer to it in ISO C++ Standard (i.e. Standard document) first. Doing so you will come along many other similar things, which will make you think about the language design.

Hope that book list helps you. Concepts from these books you will see in all well designed modern C++ frameworks.

With Kind Regards,
Ovanes

by anonymous   2017-08-20

You probably would want to read more on the documentation here.

Where <inbrackets> means a template<typename T , unsigned NUM_ELEMENTS>. According to the ISO C++ (https://isocpp.org/wiki/faq/templates)

A template is a cookie-cutter that specifies how to cut cookies that all look pretty much the same (although the cookies can be made of various kinds of dough, they’ll all have the same basic shape). In the same way, a class template is a cookie cutter for a description of how to build a family of classes that all look basically the same, and a function template describes how to build a family of similar looking functions.

Class templates are often used to build type safe containers (although this only scratches the surface for how they can be used).

For example

Consider a container class Array that acts like an array of integers:

// This would go into a header file such as "Array.h"
class Array {
public:
  Array(int len=10)                  : len_(len), data_(new int[len]) { }
 ~Array()                            { delete[] data_; }
  int len() const                    { return len_;     }
  const int& operator[](int i) const { return data_[check(i)]; }  // Subscript operators often come in pairs
  int&       operator[](int i)       { return data_[check(i)]; }  // Subscript operators often come in pairs
  Array(const Array&);
  Array& operator= (const Array&);
private:
  int  len_;
  int* data_;
  int  check(int i) const
    {
      if (i < 0 || i >= len_)
        throw BoundsViol("Array", i, len_);
      return i;
    }
};

Repeating the above over and over for Array of float, of char, of std::string, of Array-of-std::string, etc, would become tedious. Instead, you add the template<typename T> before the class definition (the T can be any identifier you want, T is just the most commonly used one, especially in examples). Then, instead of using int or float or char where referring to the data type, you use T instead. Also, instead of just referring to the class as Array, it’s Array<T> when referring to the template, or Array<int>, Array<float>, etc. when referring to a specific instantiation.

// This would go into a header file such as "Array.h"
template<typename T>
class Array {
public:
  Array(int len=10)                : len_(len), data_(new T[len]) { }
 ~Array()                          { delete[] data_; }
  int len() const                  { return len_;     }
  const T& operator[](int i) const { return data_[check(i)]; }
  T&       operator[](int i)       { return data_[check(i)]; }
  Array(const Array<T>&);
  Array(Array<T>&&);
  Array<T>& operator= (const Array<T>&);
  Array<T>& operator= (Array<T>&&);
private:
  int len_;
  T*  data_;
  int check(int i) const {
    assert(i >= 0 && i < len_);
    return i;
  }
};

Read this book it will help http://www.amazon.com/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255