6

I am interested in learning C++, and I found a book that seems to be the right fit for me. However, even though the book is quite new, some readers criticized that an earlier version of the book did not really dive into the new C++ standards (such as C++11, C++14, C++17) and rather used the "old C++ standard" (i.e., pre C++11).

While I checked if the newer version covered the new aspects of C++11 etc. (and it seemed like it covered quite a few), I am uncertain if possibly learning a pre C++11 standard would be inefficient? It seems like the new version does covers the new C++ standards (C++11 and upwards), but let's assume it does not. Would the knowledge I gain be outdated?

Again, I am new to C++, so I am not sure if the newer C++ standards completely changed the language, possibly removing/changing (integral) parts of the language which I would learn with this (possibly outdated) book. I just want to avoid learning (integral) parts of the language which are not used anymore or which are used differently nowadays (with the newer standards). However, if all the new C++ standards did was adding new features (but not removing/changing old features), I don't think learning from the book would be an issue since I could simply learn the newer features afterwards.

So in what ways did the newer C++ standards change the language, and would you say learning from a possibly outdated book is an issue?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
IT'S-ON
  • 83
  • 6
  • 2
    `auto`, lambda, for-range, "move" are the biggest/more impacting language changes. (variadic template is also a big change, but type-list seems more a niche usage (pre-C++11)). – Jarod42 Jan 18 '21 at 00:23
  • 1
    Related: https://github.com/AnthonyCalandra/modern-cpp-features – Jerry Jeremiah Jan 18 '21 at 00:24
  • 1
    Well many things in older standard is still valid code but not considered **best practice** anymore. Thus learning from an old book will not help you write code **in a modern way**. *Some old books might still be good reading while others were not even considered good reading in their time!* – Phil1970 Jan 18 '21 at 02:32
  • 1
    One thing I would **avoid from old code is manual memory management**. Better to use `std::unique_ptr` or another appropriate alternative to explicit `new` and `delete`. Some other differences are: `= default`, `= delete`, `override`, `noexcept`, `constexpr`, and many new useful libraries. – Phil1970 Jan 18 '21 at 02:42
  • You could similarly ask yourself if it is OK to learn C first *in order* to learn C++. No, just like it is not a good idea to learn Latin in order to learn French. Learning C++98 is good if you want to understand WHY modern C++ looks like it does or if you are to maintain some old code. You can learn the basic concepts, as they have remained the same, but I suggest you treat C++98 as a different language, just like C, to C++11. Also, C++20 is said to be the next major revision after C++11, and in light of it, C++98 becomes almost as obsolete as C++83. – zkoza Feb 06 '21 at 11:16

1 Answers1

8

Some code have changed in C++11, main changes, IMO, are:

  • way to "return" big object:

    • Pre-C++11, it has been recommended to use output parameter to avoid copy:
    void MakeVector(std::vector<int>& v) {
        v.clear();
        // fill v;
    }
    
    • Since C++11, no longer required for movable types, and return by value is the way to go:
    std::vector<int> MakeVector() {
        std::vector<int> v;
        // fill v;
        return v;
    }
    
  • way to iterate container:

    • Pre-C++11, it would be a mix between index and iterator way:
    void Foo(std::vector<int>& v) {
        for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) { /* *it ..*/ }
    
        for (std::size_t i = 0; i != v.size(); ++i) { /* v[i] ..*/ }
    }
    
    • Since C++11, it is shorter (and optimal (end() is computed only once)):
    void Foo(std::vector<int>& v) {
        for (int& e : v) { /* ..*/ }
    }
    
  • way to write types:

    • Pre-C++11, type should be explicitly written:
    void Foo(std::vector<int>& v) {
        std::vector<int>::iterator it = std::find(v.begin(), v.end(), 42);
        // ...
    }
    
    • Since C++11, type can be deduced:
    void Foo(std::vector<int>& v) {
        auto it = std::find(v.begin(), v.end(), 42);
        // ...
    }
    
  • way to create predicate:

    • Pre-C++11, predicate should be done outside of the function as function or class:
    bool less_than_42(int i) { return i < 42; }
    
    struct less_than_x {
        less_than_x(int x) : x(x) {}
        bool operator()(int i) const { return i < x; }
        int x;
    };
    
    void Foo(std::vector<int>& v, int x) {
        std::vector<int>::iterator it1 = std::find_if(v.begin(), v.end(), less_than_42);
        std::vector<int>::iterator it2 = std::find_if(v.begin(), v.end(), less_than_x(x));
    
        // ...
    }
    
    • Since C++11, lambda simplify stuff (dedicated function might still be useful to avoid to duplicate lambda though):
    void Foo(std::vector<int>& v, int x) {
        auto it1 = std::find_if(v.begin(), v.end(), [](int e){ return e < 42; });
        auto it2 = std::find_if(v.begin(), v.end(), [x](int e){ return e < x; });
        // ...
    }
    

There are other changes, but which less invalidate C++03 way to code.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Thanks for the clarification. It seems to me that while some code constructs have been added or changed in comparison to pre C++11, the "older" way to code is still valid and still works in the newer C++ versions (it's just not preferred), am I correct? – IT'S-ON Jan 19 '21 at 14:26
  • C++ tends to avoid/reduce breaking changes. there are Q/A about [C++11's breaking changes](https://stackoverflow.com/questions/6399615/what-breaking-changes-are-introduced-in-c11) – Jarod42 Jan 19 '21 at 15:37
  • Great list. I would perhaps add to it only the brace initialization, which can also simplify one's life. – zkoza Feb 06 '21 at 11:11