みんな代替トークン使とる。使てへんのお前だけ。 / alternative tokens

みんな代替トークン使とる。使てへんのお前だけ。 / alternative tokens

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

4cd53d17fd7e26f611822b508963f613?s=128

Miutsuru kariya

January 29, 2020
Tweet

Transcript

  1. みんな代替トークン使とる。 使てへんのお前だけ。 2020/1/29 鳥頭かりやマン 1

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

  3. 代替トークンとは? 3

  4. 代替トークンとは? 「代替」の「トークン」 まんま… なお、よく「ダイグラフ」と 呼ばれたりもするが… 4

  5. 代替トークンとは? 代替 本来 代替 本来 代替 本来 <% { and

    && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 5 見ての通り、必ずしも「ダイ」(2文字)ではなく、 キーワード型の物も結構ある。 これらの名前も予約語なので、例えば and や or と言った関数名や変数名は使えない。 ダ イ グ ラ フ で は な い 。 代 替 ト ー ク ン と 呼 べ 。
  6. 代替トークンとは? 代替 本来 代替 本来 代替 本来 <% { and

    && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 6 なお、「トークン」と名前がついている通り、コンパイラが ソースをトークン化する際に処理されるので、文字列中 や他の識別子中では代替トークンとはみなされない。 まぁ当たり前っちゃあ当たり前なんだけど…
  7. 使用例 7

  8. 使用例 使用前 #include <iostream> int main() { int a[] =

    { 114, 514, }; for (int i = 0; i < 2; ++i) { std::cout << a[i] << ", "; } std::cout << '\n'; } 8
  9. 使用例 使用後 %:include <iostream> int main() <% int a<::> =

    <% 114, 514, %>; for (int i = 0; i < 2; ++i) <% std::cout << a<:i:> << ", "; %> std::cout << '\n'; %> 9
  10. 使用例 使用後 %:include <iostream> int main() <% int a<::> =

    <% 114, 514, %>; for (int i = 0; i < 2; ++i) <% std::cout << a<:i:> << ", "; %> std::cout << '\n'; %> 10 読みやすい! (異論は認める)
  11. 使用例 …これ、使う気がしない… 11

  12. 使用例 …これ、使う気がしない… と思いましたね? 12

  13. 使用例 使用前 template <class InputIterator, class Predicate> bool all_of(InputIterator first,

    InputIterator last, Predicate pred) { for (; first != last; ++first) if (!pred(*first)) return false; return true; } 13 否定演算子が 見づらい!
  14. 使用例 使用後 template <class InputIterator, class Predicate> bool all_of(InputIterator first,

    InputIterator last, Predicate pred) { for (; first != last; ++first) if (not pred(*first)) return false; return true; } 14 否定演算子が 見やすい! (異論は認めない)
  15. 使用例 どうですか? 使いたくなってきませんか? 15

  16. ビット反転演算子が 見づらい! 使用例 使用前 const result_type Yp = (x[i] &

    ~mask) | (x[j] & mask); const size_t k = (i + m) % n; x[i] = x[k] ^ rshift<1>(Yp) ^ (a * (Yp & 1)); result_type z = x[i] ^ (rshift<u>(x[i]) & d); i = j; z ^= lshift<s>(z) & b; z ^= lshift<t>(z) & c; return z ^ rshift<l>(z); 16
  17. ビット反転演算子が 見やすい! (異論は認める) 使用例 使用後 const result_type Yp = (x[i]

    & compl mask) | (x[j] & mask); const size_t k = (i + m) % n; x[i] = x[k] ^ rshift<1>(Yp) ^ (a * (Yp & 1)); result_type z = x[i] ^ (rshift<u>(x[i]) & d); i = j; z ^= lshift<s>(z) & b; z ^= lshift<t>(z) & c; return z ^ rshift<l>(z); 17
  18. 使用例 使用後(過激派) const result_type Yp = (x<:i:> bitand compl mask)

    bitor (x<:j:> bitand mask); const size_t k = (i + m) % n; X<:i:> = x<:k:> xor rshift<1>(Yp) xor (a * (Yp bitand 1)); result_type z = x<:i:> xor (rshift<u>(x<:i:>) bitand d); i = j; z xor_eq lshift<s>(z) bitand b; z xor_eq lshift<t>(z) bitand c; return z xor rshift<l>(z); 18
  19. 何もかもが 見やすい! (異論は認める) 使用例 使用後(過激派) const result_type Yp = (x<:i:>

    bitand compl mask) bitor (x<:j:> bitand mask); const size_t k = (i + m) % n; X<:i:> = x<:k:> xor rshift<1>(Yp) xor (a * (Yp bitand 1)); result_type z = x<:i:> xor (rshift<u>(x<:i:>) bitand d); i = j; z xor_eq lshift<s>(z) bitand b; z xor_eq lshift<t>(z) bitand c; return z xor rshift<l>(z); 19
  20. 使用例 使用前 template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1,

    InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) if (!pred(*first1, *first2)) break; return pair<InputIterator1, InputIterator2>(first1, first2); } 20
  21. 使用例 使用後 template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1,

    InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { for (; first1 != last1 and first2 != last2; ++first1, ++first2) if (not pred(*first1, *first2)) break; return pair<InputIterator1, InputIterator2>(first1, first2); } 21
  22. 使用例 ところで皆さん、 代替トークンの字面に 惑わされてはいませんか? 22

  23. 使用例 使用前 struct S { S() = default; S(const S&)

    = default; S(S&&) = default; ~S() = default; }; 23 まっ、まさか…
  24. 使用例 使用後 struct S <% S() = default; S(const S

    bitand) = default; S(S and) = default; compl S() = default; %>; 24 まっ、まさか… そのまさかだ、フハ ハハハハハハハ!
  25. 使用例 使用後 struct S <% S() = default; S(const S

    bitand) = default; S(S and) = default; compl S() = default; %>; 25 まっ、まさか… そのまさかだ、フハ ハハハハハハハ! スゴい! 参照もデストラクタも 見やすい!
  26. まっ、まさか… そのまさかだ、フハ ハハハハハハハ! 使用例 使用後 struct S <% S() =

    default; S(const S bitand) = default; S(S and) = default; compl S() = default; %>; 26 スゴい! 参照もデストラクタも 見やすい! ダメ!ゼッタイ!
  27. 結論 27

  28. 結論 代替トークン普及の会からのお知らせ みんな積極的に 代替トークンを使おう! せめて忘れないであげてください!!! 28

  29. 蛇足① ちなみに、C++17で廃止されてしまったトライグラフは、トー クン化どころかプリプロセス前に処理されていたので、文字 列内とかでも問答無用で変換対象になっていた。 29 代替 本来 代替 本来 代替

    本来 ??= # ??( [ ??< { ??/ \ ??) ] ??> } ??’ ^ ??! | ??- ~
  30. 蛇足① 使用前(再掲) #include <iostream> int main() { int a[] =

    { 114, 514, }; for (int i = 0; i < 2; ++i) { std::cout << a[i] << ", "; } std::cout << '\n'; } 30
  31. 蛇足① 使用後(トライグラフ) ??=include <iostream> int main() ??< int a??(??) =

    ??< 114, 514, ??>; for (int i = 0; i < 2; ++i) ??< std::cout << a??(i??) << ", "; ??> std::cout << '\n'; ??> 31
  32. 蛇足① 使用後(トライグラフ) ??=include <iostream> int main() ??< int a??(??) =

    ??< 114, 514, ??>; for (int i = 0; i < 2; ++i) ??< std::cout << a??(i??) << ", "; ??> std::cout << '\n'; ??> 実際某青いI社のメインフレームで見たときは正直キモかった…(個人の感想です) 32 読みづらい! (異論は認める)
  33. 蛇足➁ C++のトークン化は、通常最長のトークンを切り出すことに なっている。 例) external ⇒ “extern”と“al”と言う2つのトークンではなく、 “external”と言う単一のトークン a+++++b ⇒

    “a” “++” “+” “++” “b” ではなく、“a” “++” “++” “+” “b” と言うトークン列 33
  34. 蛇足➁ しかし、代替トークンに関連した以下のような例外がある。 “<::”の後ろに続く文字が“>”でも“:”でもなかった場合、 “<”と“::”と言う2つのトークンになる。 “<:” ⇒ “{” “<::” ⇒ “<”

    と “::” “<::>” ⇒ “{” と “}” “<:::” ⇒ “{” と “::” まぁ普通この規則に引っかかることはおそらく一生のうち1度も無いとは思う… 34
  35. 蛇足➂ C言語では、キーワード型の代替トークンは言語仕様ではな く、ヘッダで提供されている。 35 代替 本来 代替 本来 代替 本来

    <% { and && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 言語仕様で提供 ヘッダiso646.hで提供
  36. みんな代替トークン使とる。 使てへんのお前だけ。 36 完 終 制作・著作 ━━━━━ ⓃⒽⓀ