- Initialization
- Type Deduction
- Inheritance
- Computational Complexity
- APIs
- Specifications
- Essential and Accidental Complexity
Effective C++ 系列的作者 Scott Meyers 在 Dconf 中 The Last Thing D Needs 聊了些 C++的特性,稍微总结一下。
Initialization
1 2 3 4 5 6 7 8 9 10 11 |
|
Type Deduction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
For
1
|
|
type deduction for cx yields:
Context | Type |
---|---|
auto | int |
decltype | const int |
template(T parameter) | int |
template(T& parameter) | const int |
template(T&& parameter) | const int& |
lambda (by-value capture) | const int |
lambda (int capture) | int |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Inheritance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
In essence, the One Definition Rule states that the same entity should have the exact same definition throughout an application, otherwise the effects are undefined.
The fundamental problem is that the code that doesn’t see the specialized version of your class template member function might still compile, is likely to link, and sometimes might even run. This is because in the absence of (a forward declaration of) the explicit specialization, the non-specialized version kicks in, likely implementing a generic functionality that works for your specialized type as well.
Computational Complexity
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
APIs
1 2 3 |
|
- set –> erase
- multiset –> erase
- map –> erase
- multimap –> erase
- unordered_set –> erase
- unordered_multiset –> erase
- unordered_map –> erase
- unordered_multimap –> erase
- list –> remove
- forward_list –> remove
Sorts can be stable or unstable. Which are guaranteed to be stable? * sort –> not guaranteed * stable_sort –> guaranteed * list::sort –> guaranteed
Specifications
Five sequence containers:
- array –> No
- deque –> Yes
- forward_list –> No(fulfill of 1 of 16)
- list –> Yes
- vector – > Yes
Essential and Accidental Complexity
Essential Complexity: due to inherent design tensions.
- Simplicity and regularity vs expressiveness.
- Abstraction and portability vs efficiency.
- New approaches vs compatibility with legacy systems.
- Expressiveness vs ability to issue good diagnostics.
Essential Complexity
1 2 3 |
|
What is the type of Point::x?
1 2 |
|
What is the type of cp.x?
C++ soluction:
1 2 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Assume typo and diagnose now?
- Wrong if later specialization offers doBaseWrk.
Assume later specialization and defer lookup until instantiation?
- If typo, imposes diagnostics for library errors on clients.
C++ solution:
- Template author has control
- doBaseWrk() -> lookup name when parsing template.
- this->doBaseWrk() -> lookup name when instantiating template.
Accidental Complexity
- ints are sometimes initialized to 0.
- By-value lambda capture somtimes retains the constness of what’s captured.
- mutable lambdas must declare a parameter list, but non-mutable lambdas don’t
- Braced initializers (e.g.”{0}”) sometimes have a type.
- Computation complexity guarantees usually meaningful.
- Elimination all container elements with a given value usually means
calling
erase
. sort
is sometimes stable.- Container “requirements” are sometimes required.