C++ Templates: The Complete Guide

Category: Programming
Author: David Vandevoorde, Nicolai M. Josuttis
4.5
All Stack Overflow 33
This Year Stack Overflow 1
This Month Stack Overflow 1

Comments

by anonymous   2019-07-21

That's because the function a<int>::b() is not instantiated, due to the fact that it is a template. When you try to instantiate it, i.e. call it like var.b();, the compiler will spit an error. You have to understand that templates are instantiated "on demand", i.e. when the compiler needs the instantiation. Otherwise only minimal syntactic verifications take place. The details regarding instantiations/name lookups in templates is a rather complicated subject, I highly recommend this book: C++ Templates: The Complete Guide by David Vandevoode and Nicolai Josuttis.

That's not the case with the first code snippet: the function has to be valid from the very beginning.

by anonymous   2019-01-13

According to the book C++ Templates: The Complete Guide Appendix B.1,

At a very high level, a call to a named function can be processed in the following way:

  1. The name is looked up to form an initial overload set.

  2. If necessary, this set is tweaked in various ways (for example, template deduction occurs).

  3. Any candidate that doesn't match the call at all (even after considering implicit conversions and default arguments) is eliminated from the overload set. This results in a set of so-called viable function candidates.

  4. Overload resolution is performed to find a best candidate. If there is one, it is selected; otherwise, the call is ambiguous.

  5. The selected candidate is checked. For example, if it is an inaccessible private member, a diagnostic is issued.

As you can see, the access authority is checked at last, so the call to fn() is ambiguous will be reported firstly at step #4.

by litb   2018-03-19

Beginner

Introductory, no previous programming experience

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

Introductory, with previous programming experience

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

With templates we simply don't have clean output facilities and there are no compilers i know of that allow you to directly view template instantiations. The closest i found regarding metaprogram debugging was a paper on Templight.

For now the best utilities seem to be:

  • static asserts & concept checks (clearly assert your assumptions)
  • the mentioned instantiation backtraces (e.g. by using static asserts)
  • letting instantiations generate warnings (boost::mpl::print might do it)
  • a tracer, a custom class that gets passed as a template argument and is used to emit runtime output (introduced by C++ Templates - The Complete Guide)
by anonymous   2017-08-20

Short summary

This is just the way the current C++11 rules are: this->bar.baz<int>() introduces a dependent name not in the current instantiation context that requires disambiguation with the template keyword, even though it is very hard to come up with an actual example of a competing parse that change the semantics of the expression this->bar.baz<int>().

Parsing ambiguity from angle brackets

First: why in general is there a need for template?

When a C++ compiler encounters an expression f<g>(0), it can interpret this either as "call the function template f for template argument g and function argument 0 and evaluate the result" or it can mean "make the comparison (f<g)>(0) for names f and g and constant 0." Without further information it cannot make this decision. This is an unfortunate consequence of the choice of angle brackets for template arguments.

In many (most) cases, the compiler does have enough context to decide whether a template expression or a comparison is being parsed. However, when a so-called dependent name (essentially a name that is explicitly or implicitly dependent on a template parameter of the current scope) is encountered, another language subtlety comes into play.

Two-phase name lookup

Because a name dependent on a template could change its meaning (e.g. through specializations) when a template is being instantiated for a concrete type, name lookup of dependent names is done in two phases (quote from C++ Templates the Complete Guide):

During the first phase, nondependent names are looked up while the template is being parsed using both the ordinary lookup rules and, if applicable, the rules for argument-dependent lookup (ADL). Unqualified dependent names (which are dependent because they look like the name of a function in a function call with dependent arguments) are also looked up that way, but the result of the lookup is not considered complete until an additional lookup is performed when the template is instantiated.

During the second phase, which occurs when templates are instantiated at a point called the point of instantiation (POI), dependent qualified names are looked up (with the template parameters replaced with the template arguments for that specific instantiation), and an additional ADL is performed for the unqualified dependent names.

Why this-> makes your code different

Using this-> inside a class template introduces a dependent name and triggers two-phase name lookup. In that case, the rule cited by @40two comes into play. The point is that the ADL at the 2nd phase can bring in new names from explicit specializations that redefine the meaning of your bar and baz and it could conceivably change the meaning of this->bar.baz<int>(0) to a comparison rather than a function template call.

Granted, for non-type template arguments such as this->bar.another_baz<0>() this would be more likely than for a type template parameter. In this related Q&A a similar discussion arose whether one could find a syntactic valid form that changes the meaning of this->f<int>() vs this->template f<int>(0), without a clear conclusion.

Note that C++11 already relaxes the rule for template disambiguation compared to C++98. Under the current rules this->f<int>() for a template<class> f() inside Foo would not require template because it is in the so-called current instantiation. See this answer from the canonical Q&A for this topic for more details

by anonymous   2017-08-20

What are C++ Expression Templates in simple terms?

Expression templates are a category of C++ template meta programming which delays evaluation of subexpressions until the full expression is known, so that optimizations (especially the elimination of temporaries) can be applied.

Are there books around that discuss numerical methods/computations using C++ Expression Templates?

I believe ET's were invented by Todd Veldhuizen who published a paper on it 15 years ago. (It seems that many older links to it are dead by now, but currently here is a version of it.) Some material about it is in David Vandevoorde's and Nicolai Josuttis' C++ Templates: The Complete Guide.

In what way, C++ Expression Templates are better than using pure C?

They allow you to write your code in an expressive high level way without losing performance. For example,

void f(const my_array<double> a1, const my_array<double> a2) 
{ 
  my_array<double> a3 = 1.2 * a1 + a1 * a2; 
  // ..
}

can be optimized all the way down to

for( my_array<double>::size_type idx=0; idx<a1.size(); ++idx ) 
  a3[idx] = 1.2*a1[idx] + a1[idx]*a2[idx]; 

which is faster, but harder to understand.

by anonymous   2017-08-20

This question is also addressed specifically in the definitive book on C++ Templates ("C++ Templates: The Definitive Guide", by Vandvoorde and Josuttis), Section 7.1, p.87 (at least in my edition):

7.1 "Class Template" or "Template Class"?

[snip]

There is some confusion about how a class that is a template is called:

The term class template states that the class is a template. That is, it is a parameterized description of a family of classes.

The term template class on the other hand has been used

  • as a synonym for class template.

  • to refer to classes generated from templates.

  • to refer to classes with a name that is a template-id.

The difference between the second and third meaning is somewhat subtle and unimportant for the remainder of the text.

Because of this imprecision, we avoid the term template class in this book.

Similarly, we use function template and member function template, but avoid template function and template member function.

(Anyone, I mean anyone, working with C++ templates should have a copy of this book, by the way.)

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: