「なぜusing namespace std;を避けるべきか」を読んだ感想

「なぜusing namespace std;を避けるべきか」を読んだ感想

序文

なぜusing namespace std;を避けるべきか を読んだのでRust交えて感想書く。

using namespace std;とは?

ちゃんと調べてないが見た感じ機能としてはRustのuseと殆ど同じようである。
ただこの場合、Rustな表現だと(絶対誰かに怒られる怒らないで)use std::* な感じだろうか。

名前衝突

正直C++よくわかんない(本当にわからない(本当にわk...))のでよくわからないが、 using namespace std;やるだけで名前衝突が起こりやすくなるようだ。
普段私はRust書いてるので意識したことはないので、手始めに名前衝突させてみようと考えた。

実験:Rustで名前衝突させてみよう

手元のVimで以下コードを書いてみた。

// Rust
use std::string::String::*;
use std::vec::Vec::*;

fn main() {
    let s = new();
}   

new()関数は値の初期化によく使われるので真っ先に思いついた。
で走らせたらコンパイルが通らない。

error[E0432]: unresolved import `std::string::String`
 --> poi.rs:1:18
  |
1 | use std::string::String::*;
  |                  ^^^^^^ Not a module `String`

error[E0432]: unresolved import `std::vec::Vec`
 --> poi.rs:2:15
  |
2 | use std::vec::Vec::*;
  |               ^^^ Not a module `Vec`

error[E0425]: cannot find function `new` in this scope
 --> poi.rs:5:10
  |
5 |     let s = new();
  |             ^^^ not found in this scope
  

要はStringVecはモジュールじゃないからだめだって。

可読性

複数のライブラリを使うときに、どの関数がどの名前空間にあるかわからないと、正しい関数を呼び出せているかわかりにくくなります。 using namespaceによって名前空間が省略されていると、それができないんですね。

C++わからない(本t...)けどこれならわかる。
Rustであれば、上述のエラーを読んだ感じなんとなくモジュールを用いる事によってによって衝突を避けられてるというのがわかる。

名前空間が深い場合においてのuse namespaceを 可読性を持ちながら有効な記述例@yumetodo先輩が書き記していた。
それが以下コード。引用

#include <chrono>
#include <iostream>
void foo(){}
int main()
{
    namespace ch = std::chrono;
    using clock = ch::high_resolution_clock;
    const auto t1 = clock::now();
    foo();
    const auto t2 = clock::now();
    std::cout << ch::duration_cast<ch::miliseconds>(t2 - t1).cout() << std::endl;
}

うーん...ちょっとめんどくさい。

まとめ

モジュール使うと上記の問題が全部解決するって。
だから皆Rust使おう。