mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
parent
974fdf4661
commit
50576c0144
|
@ -17077,6 +17077,7 @@ Source file rule summary:
|
|||
* [SF.7: Don't write `using namespace` in a header file](#Rs-using-directive)
|
||||
* [SF.8: Use `#include` guards for all `.h` files](#Rs-guards)
|
||||
* [SF.9: Avoid cyclic dependencies among source files](#Rs-cycles)
|
||||
* [SF.10: Avoid dependencies on implicitly `#included` names](#Rs-implicit)
|
||||
|
||||
* [SF.20: Use `namespace`s to express logical structure](#Rs-namespace)
|
||||
* [SF.21: Don't use an unnamed (anonymous) namespace in a header](#Rs-unnamed)
|
||||
|
@ -17411,6 +17412,76 @@ Eliminate cycles; don't just break them with `#include` guards.
|
|||
|
||||
Flag all cycles.
|
||||
|
||||
|
||||
### <a name="Rs-implicit"></a>SF.10: Avoid dependencies on implicitly `#included` names
|
||||
|
||||
##### Reason
|
||||
|
||||
Avoid surprises.
|
||||
Avoid having to change `#include`s if an `#include`d header changes.
|
||||
Avoid accidentally becoming dependent on implementation details and logically separate entities included in a header.
|
||||
|
||||
##### Example
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
void use() // bad
|
||||
{
|
||||
string s;
|
||||
cin >> s; // fine
|
||||
getline(cin,s); // error: getline() not defined
|
||||
if (s=="surprise") { // error == not defined
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
<iostream> exposes the definition of `std::string` ("why?" makes for a fun trivia question),
|
||||
but it is not required to do so by transitively including the entire `<string>` header,
|
||||
resulting in the popular beginner question "why doesn't `getline(cin,s);` work?"
|
||||
or even an occasional "`string`s cannot be compared with `==`).
|
||||
|
||||
The solution is to explicitly `#include<string>`:
|
||||
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
using namespace std;
|
||||
|
||||
void use()
|
||||
{
|
||||
string s;
|
||||
cin >> s; // fine
|
||||
getline(cin,s); // fine
|
||||
if (s=="surprise") { // fine
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
##### Note
|
||||
|
||||
Some headers exist exactly to collect a set of consistent declarations from a variety of headers.
|
||||
For example:
|
||||
|
||||
// basic_std_lib.h:
|
||||
|
||||
#include<vector>
|
||||
#include<string>
|
||||
#include<map>
|
||||
#include<iostream>
|
||||
#include<random>
|
||||
#include<vector>
|
||||
|
||||
a user can now get that set of declarations with a single `#include`"
|
||||
|
||||
#include "basic_std_lib.h"
|
||||
|
||||
This rule against implicit inclusion is not meant to prevent such deliberate aggregation.
|
||||
|
||||
##### Enforcement
|
||||
|
||||
Enforcement would require some knowledge about what in a header is meant to be "exported" to users and what is there to enable implementation.
|
||||
No really good solution is possible until we have modules.
|
||||
|
||||
### <a name="Rs-namespace"></a>SF.20: Use `namespace`s to express logical structure
|
||||
|
||||
##### Reason
|
||||
|
|
Loading…
Reference in New Issue
Block a user