How to teach C++

In the closing Keynote of this year’s Meeting C++, Nicolai Josuttis remarked how hard it can be to teach C++ with its ever expanding complexity. His example was teaching rookies about initialization in C++, i.e. whether to use assignment =, parens () or curly braces {}. He also asked for more application-level programmers to participate.

Well, I am an application programmer, and I also have experience with teaching C++. Last year I held a C++ introductory course for experienced C programmers who mostly had never used C++ before. From my experience, I can completely agree with what Nico had to say about teaching C++. The language and its subtlety can be truly overwhelming.

Most of the complexity in C++ boils down to tuning your code for optimal performance. We cannot just leave that out, can we? After all, the sole reason to use C++ is performance, right?

My approach

Performance is one key reason for using C++, no doubt about it. There is a few more, but let us not get distracted. What is even more important is the potential to optimize for performance. But you can do that later! It is actually quite crazy what performance crimes you can get away with in C++ and still have something pretty fast overall, especially with move-semantics and improved RVO.

Given that, I picked a simple subset to start with:

  • Pass by-value only, do not use pointers nor references.
  • Structure your programs around simple data-only structs and functions transforming them.
  • Make good use of the data structures and algorithms from std.

Believe me, you too can write pretty useful programs this way. This is not too far from a data-oriented style anyways.
So, yes, we can actually leave out the performance specific parts for quite some time, while still making sure our programs can be optimized eventually.

And from there?

You can gradually start introducing references and move semantics, when measurement shows copying affecting the performance. This way you can introduce tooling like a profiler and see the effects off passing things around by reference in a language where everything, by default, is passed by value. These things will start to make sense in a context.

The arguably better approach to move semantics is of course types that prevent you from copying, but allow moving. Most resources with side-effects are like this: file handles, locks, threads. You will need to introduce RAII for this to make sense, e.g. writing ctors and dtors.

But you still do not need to write templates, use virtual-function polymorphism, or even pointers. But when you get to those, you will have a good context to use them.

Have you tought C++ and some experience to share? I would like to hear about it!

7 thoughts on “How to teach C++”

  1. I’m retired for a few years but started working with C++ in early ’90s. Still do a lot of code for robotics projects. I keep up with C++ through Stroustrup’s books but he hasn’t updated for C++17 so turned to another highly recommended text.

    If I weren’t bald I’d be tearing my hair out. A topic is introduced by showing how it is done in C and then by showing the C++. No, that’s backwards. Show the preferred C++ first then the other C++ approaches and then, just for reference the C. I’m thinking here specifically of initialization since there are many alternatives but it applies in other situations.

    IMO C++ should be taught as C++ not a weird version of C. As you imply there is an application developer subset of C++ that should be taught. There is also a library developer subset. For example, libraries can use ‘void*’ for genericity but applications should never do so. (Check out STL for use of void*).

    I disagree with you about not using references. They aren’t just for performance. Passing by reference is a standard technique that should be used by all developers. Passing of pointers is passing by reference and one of the reasons they are in C.

    Keep telling myself not to start the book / extensive blog on “Pragmatic C++: An Iconoclastic Introduction”.

    1. I am not advising to teach how to do it in C first. Not at all! Much more like python, in fact. Maybe that was not really clear, but it is what I meant by utilizing the stdlib properly, e.g. use containers like vector and unordered_map – do you the high-level value-types from the stdlib (or its predecessor STL). The code usually turns out in a very functional style if you follow this.
      I absolutely agree that application level code should be different from library-level code.
      Not using references is key here. If they aren’t used to avoid copies (i.e. const-refs), they are out-parameters. Hence you got functions with side-effects. I think functions without side-effects are better in general. I dare you to give me an example where you think a function with side effects is objectively better than one without, and where the reason for that is not an optimization. Feel free to e-mail me on that, comment threads are really bad for that kind of discussion.

      1. We’re in more violent agreement than not. My comment on C first was directed at the book I was reading, not you.

        Standalone functions should not be causing side effects. That’s bad because you can’t tell from the function what else is being changed. We agree.

        Class members are in one sense all about “side effects” but they are internal to the class so the changes are local to the object.

        Again agree about using const references and not out parameters. I suspect there are some rare cases where it is appropriate. There are various ways (unfortunately like initialization?) of returning multiple values in the return value of a function. But I’d look hard at the design since maybe the design is not good, e.g. should there be a class?

        Guess I’ll disagree with Bjarne’s not doing references early. It’s a fundamental way of passing values to a function. Teaching the use of const references introduces a design mind set early where it is more likely to be ingrained as a habit. Somewhere in my nearly 30 years of C++ I had to school myself into putting the const on parameters, especially references. Old C habits die hard.

  2. As some will know, I have a long-term interest in teaching (e.g., see https://www.youtube.com/watch?v=fX2W3nNjJIo&vl=en).
    In my opinion, you cannot separate design from teaching. Teaching is an immensely important topic for C++.

    When teaching C++ (or anything else), you need to adapt to the background and need of your students.

    I have two basic approaches:

    For complete beginners, I use “Programming: Principles and Practice using C++”.
    It focuses on fundamental program development techniques.
    Like Marius Elvert, I start with call by value as the simplest and it is good enough initially.
    References and pointer come later (e.g., chapter 17 for pointers).

    For people who are already programmers, I use “A Tour of C++” (2nd edition 240 pages).
    It is deliberately short, but covers a lot. I assume that its readers can use the Web to look for details
    (e.g., cppreference.com and the C++ Core Guidelines). Its readers get pointers and reference in Chapter 1.

    I do not use “The C++ Programming Language” for teaching, only as backup material for more advanced students.

    In both cases, I try hard not to get sucked into technical subtleties.
    In both cases, I use simple data structures (e.g., std::string and std::vector) from the very beginning.
    Neither group needs to know everything about anything in C++, at least not during a first course.

    PPP is roughly C++14 and Tour2 is C++17 plus a bit from C++20.
    I use newer features to simplify code examples and explanations, never just to impress.
    As long as you don’t try to explain everything, “modern C++” can be much simpler than older C++.
    Obviously, older styles and facilities has to be explained eventually or the student cannot read
    older C and C++ code, but I postpone that until “later” when the student has the background to
    understand and appreciate the differences.

    1. That sounds very interesting, I love the two different approaches for the experience levels and I imagine it is helpful for the students to have the lectures structured around specific books like that. How much time do you take for the lectures, lets say a chapter in PPP?
      I skipped references and for the first two 3h lectures. I still feel that there is a lot of prejudice against C++ being too cumbersome. It was my main objective to show counter-examples on how to accomplish a lot with very simple, expressive code.

      1. When I taught PPP (currently, I teach graduate students), I had roughly one lecture per chapter. A lecture was 50 minutes and I gave two a week. I would have preferred a bit more time for better
        examples and more Q&A. I skipped the much of the first chapter to get to code and dispersed much of the the motivational stuff throughout the lectures as asides and examples. For real beginners
        it is important to give real-world examples of C++ use so that they can begin to grasp the relevance of what they are taught.

        Here are the slides: http://www.stroustrup.com/Programming/lecture-slides.html and here is the instructor’s guide: http://www.stroustrup.com/Programming/PPP-guide.pdf .
        Should I give this course again, I’d revise the slides (of course) and improve the support for installing FLTK. I let the students use whatever system they were comfortable with and any up-to-date C++ compiler.

        There definitely is some prejudice against C++ in parts of the teaching establishment, but it is only fair to point out that much of that is caused by really poor approaches to C++ and weak
        teaching materials. We can and must do better. Note that a study group for education to address this is being set up withing the framework of the standards committee: https://isocpp.org/std/the-committee .

  3. Also I think it’s also important to build on the state of C++17. So now Smart Pointers are a must in the chapter about pointers.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.