Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

using ディレクティブの使い方 そこで using ディレクティブ ですよ奥さん! 8

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

using ディレクティブの使い方 #include using namespace std; namespace N { void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } スッキリした! 素晴らしい! 10 using ディレクティブ入れてみた

Slide 11

Slide 11 text

余談:using 何て? いつもの C++ の予約語使いまわし芸のせい で、予約語 using を使った構文は他にもいっ ぱいあるので、ご注意を! using-declaration using-enum-declaration※ alias-declaration attribute-using-prefix ※ NEW!!! C++20!!! 11

Slide 12

Slide 12 text

みんな大好き! using ディレクティブ 12 完

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

名前空間Nに using ディレクティブ入れてみた using ディレクティブの使い方 #include namespace N { using namespace std; void hell() { cout << "Hell, World!" << endl; } } int main() { N::hell(); } これならNの外には影響なし! 素晴らしい! 16

Slide 17

Slide 17 text

using ディレクティブのワナ 17

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

using ディレクティブのワナ #include 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で使えるんじゃ…

Slide 26

Slide 26 text

using ディレクティブのワナ #include 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で使えるんじゃ… ナゾ!

Slide 27

Slide 27 text

using ディレクティブのワナ 困ったら エゾえもんに 相談だ! 27 助 け て エ ゾ え も ~ ん !

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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 英語 読めん!

Slide 32

Slide 32 text

ぐ~ぐるコンニャク~! using ディレクティブのワナ 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

using ディレクティブのワナ #include 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。

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

using ディレクティブのワナ #include namespace A { auto s = "ほげ"; } namespace B { auto s = "はげ"; void f() { using namespace A; std::cout << s << std::endl; } } int main() { B::f(); } 40 この s は "ほげ" じゃなくて "はげ"!

Slide 41

Slide 41 text

結論 41

Slide 42

Slide 42 text

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