みんな大好き!using ディレクティブ! / using directive

みんな大好き!using ディレクティブ! / using directive

C++MIX #7 の発表資料です。

4cd53d17fd7e26f611822b508963f613?s=128

Miutsuru kariya

January 29, 2020
Tweet

Transcript

  1. みんな大好き! using ディレクティブ! 2020/1/29 鳥頭かりやマン 1

  2. 初心者向けネタ発表です。 「そんなんみんな知っとるが」など、その 筋の方からのツッコミは無しの方向でお 願いします… 2

  3. using ディレクティブとは? 3

  4. using ディレクティブとは? 雑な説明 指定した名前空間のメンバを 名前空間名の修飾無しで 使えるようになる。 4

  5. using ディレクティブの 使い方 5

  6. using ディレクティブの使い方 #include <iostream> namespace N { void hell() {

    std::cout << "Hell, World!" << std::endl; } } int main() { N::hell(); } 6
  7. using ディレクティブの使い方 #include <iostream> namespace N { void hell() {

    std::cout << "Hell, World!" << std::endl; } } int main() { N::hell(); } std::が鬱陶しい! ※ いや、個人的には std::endl は基本使わないんですが、気にしない方向で… 7
  8. using ディレクティブの使い方 そこで using ディレクティブ ですよ奥さん! 8

  9. using ディレクティブの使い方 using namespace std 読み人知らず 9

  10. using ディレクティブの使い方 #include <iostream> using namespace std; namespace N {

    void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } スッキリした! 素晴らしい! 10 using ディレクティブ入れてみた
  11. 余談:using 何て? いつもの C++ の予約語使いまわし芸のせい で、予約語 using を使った構文は他にもいっ ぱいあるので、ご注意を! using-declaration

    using-enum-declaration※ alias-declaration attribute-using-prefix ※ NEW!!! C++20!!! 11
  12. みんな大好き! using ディレクティブ 12 完

  13. みんな大好き! using ディレクティブ 13 これじゃ あんまりなので…

  14. using ディレクティブの使い方 せっかく名前衝突を 避けるために名前空間作った のに、グローバル名前空間で やっちゃうのは どうなの??? 14

  15. using ディレクティブの使い方 #include <iostream> namespace N { using namespace std;

    void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } 15 名前空間Nに using ディレクティブ入れてみた
  16. 名前空間Nに using ディレクティブ入れてみた using ディレクティブの使い方 #include <iostream> namespace N {

    using namespace std; void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } これならNの外には影響なし! 素晴らしい! 16
  17. using ディレクティブのワナ 17

  18. using ディレクティブのワナ #include <iostream> namespace N { using namespace std;

    auto cout = 42; void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } 18 ちょっと名前が被っただけで… ※ そんな変な名前使わねぇよ、と言うツッコミは無しの方向で… (実際std名前空間にはめっさ名前があるから許して…)
  19. using ディレクティブのワナ #include <iostream> namespace N { using namespace std;

    auto cout = 42; void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } 19 コンパイルエラー! そりゃそうだ… ※ そんな変な名前使わねぇよ、と言うツッコミは無しの方向で… (実際std名前空間にはめっさ名前があるから許して…) ちょっと名前が被っただけで…
  20. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 20 using ディレクティブは名前空間スコー プだけじゃなくて、ローカルスコープ でも使えます!!!1!
  21. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 21 using ディレクティブは名前空間スコー プだけじゃなくて、ローカルスコープ でも使えます!!!1! やっぱり コンパイルエラー!
  22. using ディレクティブは名前空間スコー プだけじゃなくて、ローカルスコープ でも使えます!!!1! using ディレクティブのワナ #include <iostream> namespace N

    { auto cout = 42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 22 やっぱり コンパイルエラー! 何で!?
  23. using ディレクティブのワナ もう一度 ソースを よ~く見てみる… 23

  24. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 24 自分で定義したcoutは 名前空間スコープにある…
  25. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 25 自分で定義したcoutは 名前空間スコープにある… std::coutは当然std名前空間にあるけど、 usingディレクティブでローカルスコープに 持ってきたんだから、名前空間Nよりも内側 にあるのでcoutで使えるんじゃ…
  26. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 26 自分で定義したcoutは 名前空間スコープにある… std::coutは当然std名前空間にあるけど、 usingディレクティブでローカルスコープに 持ってきたんだから、名前空間Nよりも内側 にあるのでcoutで使えるんじゃ… ナゾ!
  27. using ディレクティブのワナ 困ったら エゾえもんに 相談だ! 27 助 け て エ

    ゾ え も ~ ん !
  28. using ディレクティブのワナ 困ったら エゾえもんに 相談だ! 28 質 問 で は

    な い 助 け て エ ゾ え も ~ ん !
  29. using ディレクティブのワナ 困ったら 原典(規格書)に あたってみよう! http://eel.is/c++draft マジで神! 29

  30. using ディレクティブのワナ 9.8.3 Using namespace directive [namespace.udir] 2. During unqualified

    name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the using- directive and the nominated namespace. http://eel.is/c++draft/namespace.udir#2 30
  31. using ディレクティブのワナ 9.8.3 Using namespace directive [namespace.udir] 2. During unqualified

    name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the using- directive and the nominated namespace. http://eel.is/c++draft/namespace.udir#2 31 英語 読めん!
  32. ぐ~ぐるコンニャク~! using ディレクティブのワナ 32

  33. using ディレクティブのワナ 9.8.3名前空間ディレクティブの使用 [namespace.udir] 2.修飾されていない名前のルックアップ中、名前は、 usingディレクティブと指定されたネームスペースの 両方を含む最も近い囲みネームスペースで宣言さ れているように表示されます。 http://eel.is/c++draft/namespace.udir#2 ちと微妙だけどまぁ雰囲気は分かるかな…

    33
  34. using ディレクティブのワナ もう一度 ソースを よ~く見てみる… 34

  35. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 35 このusingディレクティブを囲む 名前空間はN。
  36. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 36 このusingディレクティブを囲む 名前空間はN。 このusingディレクティブで指定 された名前空間はstd。
  37. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 37 Nとstdの両方を囲む最も近い名前 空間は、グローバル名前空間。 このusingディレクティブを囲む 名前空間はN。 このusingディレクティブで指定 された名前空間はstd。
  38. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 38 つまり、std::coutはグローバル 名前空間にあるように見える。 一方、自分で定義したcout変数は 名前空間Nにある。
  39. using ディレクティブのワナ #include <iostream> namespace N { auto cout =

    42; void hell() { using namespace std; cout << "Hell, World!" << endl; } } int main() { N::hell(); } 39 この場合 std::coutは 単純名では 見えない!!!
  40. using ディレクティブのワナ #include <iostream> namespace A { auto s =

    "ほげ"; } namespace B { auto s = "はげ"; void f() { using namespace A; std::cout << s << std::endl; } } int main() { B::f(); } 40 この s は "ほげ" じゃなくて "はげ"!
  41. 結論 41

  42. 結論 using ディレクティブは用法用量 を守って正しくお使いください 他のワナとしてusingディレクティブは推移的ってのもあるので(usingディレクティブで指定 した名前空間にusingディレクティブがあると、連鎖的にそいつの影響も受ける)、個人的に は使わないことをお勧めします。 using-declarationやnamespace-alias-definitionならもうちょっと挙動が素直なので… 42