style: fix code indentation

This commit is contained in:
Thibault Kruse 2016-08-23 11:58:20 +02:00
parent 67191255fa
commit 5aea4a1fef

View File

@ -523,8 +523,8 @@ Some language constructs express intent better than others.
If two `int`s are meant to be the coordinates of a 2D point, say so:
draw_line(int, int, int, int); // obscure
draw_line(Point, Point); // clearer
draw_line(int, int, int, int); // obscure
draw_line(Point, Point); // clearer
##### Enforcement
@ -3287,16 +3287,16 @@ This was primarily to avoid code of the form `(a = b) = c` -- such code is not c
##### Example
class Foo
{
public:
...
Foo& operator=(const Foo& rhs) {
// Copy members.
...
return *this;
}
};
class Foo
{
public:
...
Foo& operator=(const Foo& rhs) {
// Copy members.
...
return *this;
}
};
##### Enforcement
@ -4653,16 +4653,16 @@ A class with members that all have default constructors implicitly gets a defaul
Beware that built-in types are not properly default constructed:
struct X {
string s;
int i;
string s;
int i;
};
void f()
{
X x; // x.s is initialized to the empty string; x.i is uninitialized
X x; // x.s is initialized to the empty string; x.i is uninitialized
cout << x.s << ' ' << x.i << '\n';
++x.i;
cout << x.s << ' ' << x.i << '\n';
++x.i;
}
Statically allocated objects of built-in types are by default initialized to `0`, but local built-in variables are not.
@ -4671,8 +4671,8 @@ Thus, code like the example above may appear to work, but it relies on undefined
Assuming that you want initialization, an explicit default initialization can help:
struct X {
string s;
int i {}; // default initialize (to 0)
string s;
int i {}; // default initialize (to 0)
};
##### Enforcement
@ -5960,7 +5960,7 @@ Interfaces should normally be composed entirely of public pure virtual functions
unique_ptr<Goof> p {new Derived{"here we go"}};
f(p.get()); // use Derived through the Goof interface
g(p.get()); // use Derived through the Goof interface
} // leak
} // leak
The `Derived` is `delete`d through its `Goof` interface, so its `string` is leaked.
Give `Goof` a virtual destructor and all is well.
@ -6176,8 +6176,8 @@ the more benefits we gain - and the less stable the hierarchy is.
This Shape hierarchy can be rewritten using interface inheritance:
class Shape { // pure interface
public:
class Shape { // pure interface
public:
virtual Point center() const = 0;
virtual Color color() const = 0;
@ -6187,7 +6187,7 @@ This Shape hierarchy can be rewritten using interface inheritance:
virtual void redraw() = 0;
// ...
};
};
Note that a pure interface rarely have constructors: there is nothing to construct.
@ -6256,8 +6256,8 @@ Now `Shape` is a poor example of a class with an implementation,
but bear with us because this is just a simple example of a technique aimed at more complex hierarchies.
class Impl::Circle : public Circle, public Impl::Shape { // implementation
public:
class Impl::Circle : public Circle, public Impl::Shape { // implementation
public:
// constructors, destructor
int radius() { /* ... */ }
@ -8801,7 +8801,7 @@ comment.
##### Example, bad
char *p, c, a[7], *pp[7], **aa[10]; // yuck!
char *p, c, a[7], *pp[7], **aa[10]; // yuck!
**Exception**: a function declaration can contain several function argument declarations.
@ -9124,8 +9124,8 @@ The rules for `{}` initialization are simpler, more general, less ambiguous, and
##### Example
int x {f(99)};
vector<int> v = {1, 2, 3, 4, 5, 6};
int x {f(99)};
vector<int> v = {1, 2, 3, 4, 5, 6};
##### Exception
@ -9590,15 +9590,15 @@ Readability: the complete logic of the loop is visible "up front". The scope of
##### Example
for (int i = 0; i < vec.size(); i++) {
// do work
// do work
}
##### Example, bad
int i = 0;
while (i < vec.size()) {
// do work
i++;
// do work
i++;
}
##### Enforcement
@ -11276,7 +11276,7 @@ If a `thread` joins, we can safely pass pointers to objects in the scope of the
auto q = make_unique<int>(99);
raii_thread t3(f, q.get()); // OK
// ...
}
}
An `raii_thread` is a `std::thread` with a destructor that joined and cannot be `detached()`.
By "OK" we mean that the object will be in scope ("live") for as long as a `thread` can use the pointer to it.
@ -11321,7 +11321,7 @@ If a `thread` is detached, we can safely pass pointers to static and free store
t2.detach();
t3.detach();
// ...
}
}
By "OK" we mean that the object will be in scope ("live") for as long as a `thread` can use the pointers to it.
By "bad" we mean that a `thread` may use a pointer after the pointed-to object is destroyed.
@ -11567,7 +11567,7 @@ Thread creation is expensive.
void master(istream& is)
{
for (Message m; is >> m; )
for (Message m; is >> m; )
run_list.push_back(new thread(worker, m));
}
@ -11579,14 +11579,14 @@ Instead, we could have a set of pre-created worker threads processing the messag
void master(istream& is)
{
for (Message m; is >> m; )
for (Message m; is >> m; )
work.put(n);
}
void worker()
{
for (Message m; m = work.get(); ) {
// process
// process
}
}
@ -12752,20 +12752,20 @@ In such cases, "crashing" is simply leaving error handling to the next level of
void f(int n)
{
// ...
p = static_cast<X*>(malloc(n, X));
if (p == nullptr) abort(); // abort if memory is exhausted
// ...
}
// ...
p = static_cast<X*>(malloc(n, X));
if (p == nullptr) abort(); // abort if memory is exhausted
// ...
}
Most programs cannot handle memory exhaustion gracefully anyway. This is roughly equivalent to
void f(int n)
{
// ...
p = new X[n]; // throw if memory is exhausted (by default, terminate)
// ...
}
// ...
p = new X[n]; // throw if memory is exhausted (by default, terminate)
// ...
}
Typically, it is a good idea to log the reason for the "crash" before exiting.
@ -14230,7 +14230,7 @@ Semiregular requires default constructible.
vector<int> v(10);
bool b = 1 == bad;
bool b2 = v.size() == bad;
}
}
}
This prints `T0` and `Bad`.
@ -14587,27 +14587,27 @@ When `concept`s become widely available such alternatives can be distinguished d
There are three major ways to let calling code customize a template.
template<class T>
// Call a member function
void test1(T t)
{
t.f(); // require T to provide f()
}
template<class T>
// Call a member function
void test1(T t)
{
t.f(); // require T to provide f()
}
template<class T>
void test2(T t)
// Call a nonmember function without qualification
{
f(t); // require f(/*T*/) be available in caller's scope or in T's namespace
}
template<class T>
void test2(T t)
// Call a nonmember function without qualification
{
f(t); // require f(/*T*/) be available in caller's scope or in T's namespace
}
template<class T>
void test3(T t)
// Invoke a "trait"
{
test_traits<T>::f(t); // require customizing test_traits<>
// to get non-default functions/types
}
template<class T>
void test3(T t)
// Invoke a "trait"
{
test_traits<T>::f(t); // require customizing test_traits<>
// to get non-default functions/types
}
A trait is usually a type alias to compute a type,
a `constexpr` function to compute a value,
@ -16291,10 +16291,10 @@ Candidates include:
To suppress enforcement of a profile check, place a `suppress` annotation on a language contract. For example:
[[suppress(bounds)]] char* raw_find(char* p, int n, char x) // find x in p[0]..p[n-1]
{
// ...
}
[[suppress(bounds)]] char* raw_find(char* p, int n, char x) // find x in p[0]..p[n-1]
{
// ...
}
Now `raw_find()` can scramble memory to its heart's content.
Obviously, suppression should be very rare.