可能学习旧版的C++标准

6

我有兴趣学习C++,找到了一本看起来适合我的书。但是,尽管这本书很新,一些读者批评早期版本的书没有深入探讨新的C++标准(如C++11、C++14、C++17),而是使用了“旧的C++标准”(即C++11之前的标准)。

虽然我检查了新版本是否涵盖了C++11等新方面(似乎覆盖了相当多),但我不确定学习旧版C++标准是否低效?如果假设新版本没有涵盖新的C++标准,那么我获得的知识会过时吗?

再次说明,我对C++还不熟悉,因此不确定新的C++标准是否完全改变了语言,可能删除/更改了语言的(整体)部分,而这些部分则在我学习这本(可能已过时的)书中学习。我只是想避免学习不再使用或用于现代化方式的(整体)部分的语言。但是,如果所有新的C++标准只是添加新功能(但没有删除/更改旧功能),我认为从这本书中学习不会有问题,因为我可以随后学习新功能。

那么新的C++标准如何改变语言,你认为从可能已过时的书中学习是否是一个问题?


2
"auto"、lambda、for-range和"move"是最大/最有影响力的语言变化。(可变参数模板也是一个重大变化,但类型列表似乎更多是一个小众用途(C++11之前)。) - Jarod42
1
相关链接:https://github.com/AnthonyCalandra/modern-cpp-features - Jerry Jeremiah
1
许多旧标准中的许多内容仍然是有效的代码,但不再被认为是最佳实践。因此,从一本旧书中学习将无法帮助您以现代方式编写代码。有些旧书可能仍然是好读物,而其他一些甚至在它们的时代也不被认为是好读物! - Phil1970
1
我在旧代码中避免手动内存管理。最好使用std::unique_ptr或其他适当的替代方法来替换显式的newdelete。一些其他区别是:= default= deleteoverridenoexceptconstexpr以及许多新的有用库。 - Phil1970
你可以问自己,是否先学习C以便于学习C++。实际上不行,就像学习拉丁语后再去学法语一样不好。如果你想理解现代C++的设计思想或者需要维护一些旧代码,学习C++98是很好的选择。虽然基本概念一直没有改变,但我建议把C++98当作一门不同的语言来学习,就像从C到C++11那样。此外,据说C++20是C++11之后的下一个重大修订版本,在这种情况下,C++98几乎和C++83一样过时了。 - zkoza
1个回答

8

在C++11中,一些代码发生了变化,我认为主要的变化如下:

  • 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; });
        // ...
    }
    

还有其他变化,但这些变化不太使旧的C++03代码失效。


感谢您的澄清。在我看来,虽然与 C++11 之前相比添加或更改了一些代码结构,但“旧”的编码方式仍然有效,并且在新的 C++ 版本中仍然可以工作(只是不被推荐),我理解的对吗? - IT'S-ON
C++倾向于避免/减少破坏性变更。关于C++11的破坏性变更,有一些问答。 - Jarod42
很棒的列表。我可能会添加花括号初始化,这也可以简化生活。 - zkoza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接