86 lines
2.8 KiB
Plaintext
86 lines
2.8 KiB
Plaintext
== Why is this an issue?
|
||
|
||
``++auto++`` is a type placeholder that may be used in variable declarations to instruct the compiler to infer the type from the initializer.
|
||
|
||
|
||
The use of `auto` reduces unnecessary boilerplate in situations where the type of the variable is apparent from the context (see rule S5827). In other situations, though, whether `auto` increases or decreases readability is a matter of personal taste.
|
||
|
||
|
||
In the case of variables initialized from a function that conventionally returns an iterator (e.g., `begin`, `end`, `std::find`), it is clear that the type of the variable is some iterator. Spelling the exact type of the iterator in such a situation does not improve the clarity of the code, especially considering the usual verbosity of such types. The same can be said for functions returning ranges.
|
||
|
||
|
||
This rule raises an issue on the declaration of a variable that is initialized with the return value of a function that conventionally returns an iterator when the variable is declared with an explicit type equal to the function's return type. The detected functions are:
|
||
|
||
* `begin` and `end` functions and their const and reverse variants
|
||
* standard algorithms that return iterators or ranges
|
||
|
||
|
||
|
||
=== Noncompliant code example
|
||
|
||
[source,cpp]
|
||
----
|
||
std::vector<int>::iterator someFunction(std::vector<int>& v);
|
||
|
||
void f() {
|
||
std::vector<int> v;
|
||
const std::vector<int>& cv = v;
|
||
|
||
std::vector<int>::iterator it1 = v.begin(); // Noncompliant
|
||
std::vector<int>::const_iterator it2 = v.cbegin(); // Noncompliant
|
||
std::vector<int>::const_iterator it3 = cv.cbegin(); // Noncompliant
|
||
std::vector<int>::const_iterator it4 = std::begin(cv); // Noncompliant
|
||
|
||
std::vector<int>::iterator it5 = std::find(v.begin(), v.end(), 10); // Noncompliant
|
||
|
||
std::map<int, std::string> m;
|
||
if (std::map<int, std::string>::iterator it = m.find(20); it != m.end()) { // Noncompliant
|
||
// do something
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
=== Compliant solution
|
||
|
||
[source,cpp]
|
||
----
|
||
std::vector<int>::iterator someFunction(std::vector<int>& v);
|
||
|
||
void f() {
|
||
std::vector<int> v;
|
||
const std::vector<int>& cv = v;
|
||
|
||
auto it1 = v.begin();
|
||
auto it2 = v.cbegin();
|
||
auto it3 = cv.cbegin();
|
||
auto it4 = std::begin(cv);
|
||
|
||
std::vector<int>::const_iterator it5 = v.begin(); // Compliant, the type is different
|
||
std::vector<int>::iterator it6 = someFunction(10); // Compliant, the function is not a well-known function returning an iterator
|
||
|
||
auto it7 = std::find(v.begin(), v.end(), 10);
|
||
std::vector<int>::iterator it8 = someFunction(10);
|
||
|
||
std::map<int, std::string> m;
|
||
if (auto it = m.find(20); it != m.end()) {
|
||
// do something
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
== Resources
|
||
|
||
* S5827 - use auto to avoid repetition of types
|
||
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
'''
|
||
== Comments And Links
|
||
(visible only on this page)
|
||
|
||
=== relates to: S5827
|
||
|
||
endif::env-github,rspecator-view[]
|