rspec/rules/S5829/cfamily/rule.adoc

109 lines
2.4 KiB
Plaintext
Raw Normal View History

2021-04-28 16:49:39 +02:00
C+11 introduced “Uniform initialization”/"list initialization". It is a way to initialize an object from a braced-init-list. This adds a third way to initialize objects in {cpp} on top of parentheses and equal signs.
----
int a{1}; // braces initialization
int b(1); // parentheses initialization
int c=1; // equal sign initialization
----
“Uniform initialization” was introduced to address the confusion of the many initialization syntaxes in {cpp} and to give a syntax that, in concept, can be used in all initialization scenarios. It helps to:
* Initialize container in a way that wasn't possible before:
----
// Before
std::vector<int> v;
v.push_back(1);
v.push_back(2);
// After
std::vector<int>{1,2,3};
----
* Avoid narrowing:
----
double d=2.5;
int i{d}; // Compilation error
----
* Avoid the most vexing parse:
----
class A{};
A a(); // Compilation error declares a function named a that returns A.
A a{}; // Call A constructor
----
That is why “Uniform initialization” should be preferred.
2021-04-28 16:49:39 +02:00
== Noncompliant Code Example
----
struct A {
A(int i, int j, int z) {
...
}
};
void f() {
A a(1,2,3); // Noncompliant
}
struct B {
A a = A(1, 2, 3); // Noncompliant
};
----
2021-04-28 16:49:39 +02:00
== Compliant Solution
----
struct A {
A(int i, int j, int z) {
...
}
};
void f() {
A a{1,2,3};
}
struct B {
A a{1, 2, 3};
};
----
2021-04-28 16:49:39 +02:00
== Exceptions
* In some situations, “Uniform initialization” has surprising behavior. for example, in constructor overload resolution, “Uniform initialization” prefers the constructor with "std::initializer_list" as a parameter if possible, even if another constructor seems like a better match. Like in the "std::vector" case, you might need to go back to parentheses in order to call the non "intializer_list" constructor:
----
vector<int> v1(5, 10); // 5 copies of the value 10
----
* When "=" is after "auto". This might be needed to enforce deduction to initializer_list: 
----
auto i1 {1}; // int with the value 1
auto i2 = {1}; // std::initializer_list<int> with an element equal to 1
----
* In single argument cases, "=" is okay:
----
int i = 39;
----
* When the braces are after the "=":
----
vector<int> v = { 1, 2, 4 };
----
2021-04-28 16:49:39 +02:00
== See
* https://github.com/isocpp/CppCoreGuidelines/blob/8e82f0a0d9ba3992af2d61480250e1c577df4a28/CppCoreGuidelines.md#es23-prefer-the\--initializer-syntax[{cpp} Core Guidelines ES.23] - Prefer the {} initializer syntax