Show Lecture.SymbolAmbiguity as a slide show.
CS253 Symbol Ambiguity
or
“Them there namespacies is trickier then I done thought!”
The __cplusplus
symbol
% cp ~/Example/version.cc .
% cat version.cc
#include <iostream>
int main() {
std::cout << __cplusplus << '\n';
}
% g++ -std=c++98 -Wall version.cc && ./a.out
199711
% g++ -std=c++11 -Wall version.cc && ./a.out
201103
__cplusplus
, an int
, is the YYYYMM of the C++ standard in use.
- Released in 1997, ratified in 1998?
#include <iostream>
#include <string>
#include <utility>
using namespace std;
void move(const string &s) {
cout << "moving " << s << '\n';
}
int main() {
cout << __cplusplus << '\n';
move("umbrella");
}
199711
moving umbrella
#include <iostream>
#include <string>
#include <utility>
using namespace std;
void move(const string &s) {
cout << "moving " << s << '\n';
}
int main() {
cout << __cplusplus << '\n';
move("umbrella");
}
201103
- Only changed
-std=c++98
to -std=c++11
.
#include <iostream>
#include <string>
#include <utility>
using namespace std;
void move(const string &s) {
cout << "moving " << s << '\n';
}
int main() {
cout << __cplusplus << '\n';
move("umbrella");
}
201103
- C++ 11’s
std::
move
is a better match for "umbrella"
.
- New compiler, different behavior. 😱
Explicit std::
, C++ 98
#include <iostream>
#include <string>
#include <utility>
void move(const std::string &s) {
std::cout << "moving " << s << '\n';
}
int main() {
std::cout << __cplusplus << '\n';
move("umbrella");
}
199711
moving umbrella
- Some avoid
using namespace
, and sprinkle their code with std::
.
- It's not pretty«
Explicit std::
, C++ 11
#include <iostream>
#include <string>
#include <utility>
void move(const std::string &s) {
std::cout << "moving " << s << '\n';
}
int main() {
std::cout << __cplusplus << '\n';
move("umbrella");
}
201103
moving umbrella
Selective using
, C++ 98
#include <iostream>
#include <string>
#include <utility>
using std::string;
using std::cout;
void move(const string &s) {
cout << "moving " << s << '\n';
}
int main() {
cout << __cplusplus << '\n';
move("umbrella");
}
199711
moving umbrella
- Some people apply selective
using
declarations.
- It's not pretty, either, but at least the tedious part is all together.
Selective using
, C++ 11
#include <iostream>
#include <string>
#include <utility>
using std::string;
using std::cout;
void move(const string &s) {
cout << "moving " << s << '\n';
}
int main() {
cout << __cplusplus << '\n';
move("umbrella");
}
201103
moving umbrella
☼☂⛅☁☔
Do you carry an umbrella every day, or only when the
weather report predicts rain?
If you carry an umbrella every day, then you’re always dry,
but you have the bother of carrying an umbrella all the time.
If you only carry it when rain is predicted, then you’ll get wet
once in a while. However, you don’t have to lug around an umbrella
when you don’t need it.
It’s a trade-off. Which price do you want to pay? Constant carrying,
or occasional moisture?
Trade-offs
Similarly …
- Without any
using
at all, you pay the price of your code
being littered with std::
prefixes.
cout << setw(5) << setfill('*') << hex << 42 << endl;
std::cout << std::setw(5) << std::setfill('*') << std::hex << 42 << std::endl;
***2a
***2a
- With selective
using
declarations, you have to keep adding
them as you change your code. They’re all at the top of the file,
so they don’t get in the way of reading the real code.
#include <iostream>
using std::cin;
using std::cout;
using std::getline;
using namespace std;
Trade-offs
Your choice! My opinions:
std::cout << x << std::endl
makes the code difficult
to read. It’s hard to get past the litter of std::
to see the real code. Perhaps you get used to it.
- Prof. Draper favors
using
std::cin
,
and he’s one of the two finest C++ programmers in the CS Department,
so there’s a lot to be said for that.
- I throw caution to the winds with
using namespace
std
.
- I haven’t had a problem … yet.