You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CppCoreGuidelines.md
+18-18Lines changed: 18 additions & 18 deletions
Original file line number
Diff line number
Diff line change
@@ -523,8 +523,8 @@ Some language constructs express intent better than others.
523
523
524
524
If two `int`s are meant to be the coordinates of a 2D point, say so:
525
525
526
-
drawline(int, int, int, int); // obscure
527
-
drawline(Point, Point); // clearer
526
+
draw_line(int, int, int, int); // obscure
527
+
draw_line(Point, Point); // clearer
528
528
529
529
##### Enforcement
530
530
@@ -2671,23 +2671,23 @@ possibly with the extra convenience of `tie` at the call site.
2671
2671
}
2672
2672
2673
2673
C++98's standard library already used this style, because a `pair` is like a two-element `tuple`.
2674
-
For example, given a `set<string> myset`, consider:
2674
+
For example, given a `set<string> my_set`, consider:
2675
2675
2676
2676
// C++98
2677
-
result = myset.insert("Hello");
2677
+
result = my_set.insert("Hello");
2678
2678
if (result.second) do_something_with(result.first); // workaround
2679
2679
2680
2680
With C++11 we can write this, putting the results directly in existing local variables:
2681
2681
2682
2682
Sometype iter; // default initialize if we haven't already
2683
2683
Someothertype success; // used these variables for some other purpose
2684
2684
2685
-
tie(iter, success) = myset.insert("Hello"); // normal return value
2685
+
tie(iter, success) = my_set.insert("Hello"); // normal return value
2686
2686
if (success) do_something_with(iter);
2687
2687
2688
2688
With C++17 we should be able to use "structured bindings" to declare and initialize the multiple variables:
2689
2689
2690
-
if (auto [ iter, success ] = myset.insert("Hello"); success) do_something_with(iter);
2690
+
if (auto [ iter, success ] = my_set.insert("Hello"); success) do_something_with(iter);
2691
2691
2692
2692
##### Exception
2693
2693
@@ -5400,13 +5400,13 @@ To prevent slicing, because the normal copy operations will copy only the base p
5400
5400
};
5401
5401
5402
5402
class D : public B {
5403
-
string moredata; // add a data member
5403
+
string more_data; // add a data member
5404
5404
// ...
5405
5405
};
5406
5406
5407
5407
auto d = make_unique<D>();
5408
5408
5409
-
// oops, slices the object; gets only d.data but drops d.moredata
5409
+
// oops, slices the object; gets only d.data but drops d.more_data
5410
5410
auto b = make_unique<B>(d);
5411
5411
5412
5412
##### Example
@@ -5419,7 +5419,7 @@ To prevent slicing, because the normal copy operations will copy only the base p
5419
5419
};
5420
5420
5421
5421
class D : public B {
5422
-
string moredata; // add a data member
5422
+
string more_data; // add a data member
5423
5423
unique_ptr<B> clone() override { return /* D object */; }
5424
5424
// ...
5425
5425
};
@@ -15120,14 +15120,14 @@ Use the least-derived class that has the functionality you need.
15120
15120
};
15121
15121
15122
15122
// bad, unless there is a specific reason for limiting to Derived1 objects only
15123
-
void myfunc(Derived1& param)
15123
+
void my_func(Derived1& param)
15124
15124
{
15125
15125
use(param.f());
15126
15126
use(param.g());
15127
15127
}
15128
15128
15129
15129
// good, uses only Base interface so only commit to that
15130
-
void myfunc(Base& param)
15130
+
void my_func(Base& param)
15131
15131
{
15132
15132
use(param.f());
15133
15133
use(param.g());
@@ -16123,29 +16123,29 @@ Sometimes you may be tempted to resort to `const_cast` to avoid code duplication
16123
16123
class Bar;
16124
16124
16125
16125
class Foo {
16126
-
Bar mybar;
16126
+
Bar my_bar;
16127
16127
public:
16128
16128
// BAD, duplicates logic
16129
16129
Bar& get_bar() {
16130
-
/* complex logic around getting a non-const reference to mybar */
16130
+
/* complex logic around getting a non-const reference to my_bar */
16131
16131
}
16132
16132
16133
16133
const Bar& get_bar() const {
16134
-
/* same complex logic around getting a const reference to mybar */
16134
+
/* same complex logic around getting a const reference to my_bar */
16135
16135
}
16136
16136
};
16137
16137
16138
16138
Instead, prefer to share implementations. Normally, you can just have the non-`const` function call the `const` function. However, when there is complex logic this can lead to the following pattern that still resorts to a `const_cast`:
16139
16139
16140
16140
class Foo {
16141
-
Bar mybar;
16141
+
Bar my_bar;
16142
16142
public:
16143
16143
// not great, non-const calls const version but resorts to const_cast
/* the complex logic around getting a const reference to mybar */
16148
+
/* the complex logic around getting a const reference to my_bar */
16149
16149
}
16150
16150
};
16151
16151
@@ -16154,11 +16154,11 @@ Although this pattern is safe when applied correctly, because the caller must ha
16154
16154
Instead, prefer to put the common code in a common helper function -- and make it a template so that it deduces `const`. This doesn't use any `const_cast` at all:
16155
16155
16156
16156
class Foo {
16157
-
Bar mybar;
16157
+
Bar my_bar;
16158
16158
16159
16159
template<class T> // good, deduces whether T is const or non-const
16160
16160
static auto get_bar_impl(T& t) -> decltype(t.get_bar())
16161
-
{ /* the complex logic around getting a possibly-const reference to mybar */ }
16161
+
{ /* the complex logic around getting a possibly-const reference to my_bar */ }
0 commit comments