質問するログイン新規登録

回答編集履歴

6

追記

2018/11/12 06:30

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -101,4 +101,10 @@
101
101
  `1 << 2`という文字列のまま扱われるのが厄介なんですよね、マクロの場合。
102
102
  片っ端から括弧を付ければ良いわけですが、手間がメリットに釣り合わないようにも感じられます。
103
103
 
104
- [PRE00-C. 関数形式マクロよりもインライン関数やスタティック関数を使う](https://www.jpcert.or.jp/sc-rules/c-pre00-c.html)
104
+ [PRE00-C. 関数形式マクロよりもインライン関数やスタティック関数を使う](https://www.jpcert.or.jp/sc-rules/c-pre00-c.html)
105
+ なお、リンク先で紹介されている『例外』も、C++ならある程度代替可能です。
106
+ 0. PRE00-C-EX1(ローカル関数) ⇒ ラムダでクロージャを作れば良い
107
+ 0. PRE00-C-EX3(コンパイル時定数) ⇒ constexpr
108
+ 0. PRE00-C-EX4(型総称関数) ⇒ template
109
+
110
+ トークンの連結は、C++でもできそうに無いですが。

5

追記

2018/11/12 06:30

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -99,4 +99,6 @@
99
99
  ```
100
100
 
101
101
  `1 << 2`という文字列のまま扱われるのが厄介なんですよね、マクロの場合。
102
- 片っ端から括弧を付ければ良いわけですが、手間がメリットに釣り合わないようにも感じられます。
102
+ 片っ端から括弧を付ければ良いわけですが、手間がメリットに釣り合わないようにも感じられます。
103
+
104
+ [PRE00-C. 関数形式マクロよりもインライン関数やスタティック関数を使う](https://www.jpcert.or.jp/sc-rules/c-pre00-c.html)

4

断定するほどの論拠はないか

2018/11/12 06:21

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -99,4 +99,4 @@
99
99
  ```
100
100
 
101
101
  `1 << 2`という文字列のまま扱われるのが厄介なんですよね、マクロの場合。
102
- 片っ端から括弧を付ければ良いわけですが、デメリットがメリットに釣り合いません
102
+ 片っ端から括弧を付ければ良いわけですが、手間がメリットに釣り合わなようにも感じられ

3

追記

2018/11/12 06:08

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -74,4 +74,29 @@
74
74
  **実行結果** [Wandbox](https://wandbox.org/permlink/pteSBzNz3tJeTC2L)
75
75
  ```plain
76
76
  1 2 3
77
- ```
77
+ ```
78
+
79
+ さらなるおまけ
80
+ ---
81
+ マクロを使うと、見づらさ以上の弊害があります。
82
+ 競プロ界隈ではしばしば使われるようですが、リスクは理解しておきたいものです。
83
+ ```C++
84
+ #include <iostream>
85
+
86
+ #define PRINT_1(x) std::cout << x << "\n";
87
+ #define PRINT_2(x) std::cout << (x) << "\n";
88
+
89
+ template<typename T>
90
+ void print(const T& arg) {
91
+ std::cout << arg << "\n";
92
+ }
93
+
94
+ int main() {
95
+ print (1 << 2); // 4
96
+ PRINT_1(1 << 2); // 12
97
+ PRINT_2(1 << 2); // 4
98
+ }
99
+ ```
100
+
101
+ `1 << 2`という文字列のまま扱われるのが厄介なんですよね、マクロの場合。
102
+ 片っ端から括弧を付ければ良いわけですが、デメリットがメリットに釣り合いません。

2

修正

2018/11/12 06:05

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -18,7 +18,7 @@
18
18
  また、どうしてもマクロを使いたいときは、UPPER_SNAIL_CASEで命名するのが一般的です。
19
19
  ```C++
20
20
  #define PRINT(x) \
21
- std::cout << x << "\n"
21
+ std::cout << (x) << "\n"
22
22
  ```
23
23
 
24
24
  **メンバ変数の取り扱い**
@@ -43,4 +43,35 @@
43
43
  ```
44
44
 
45
45
  これも好みの問題ですが、
46
- せっかく単項インクリメントが用意されているのでその恩恵に預かっても良いのかな、と。
46
+ せっかく単項インクリメントが用意されているのでその恩恵に預かっても良いのかな、と。
47
+
48
+ **範囲外へのアクセス**
49
+ 他言語と比べて、C/C++での生配列への範囲外アクセスは感知しづらいです。
50
+ 範囲内であるか前以て判定する処理を書いておけば安心です。
51
+
52
+ ---
53
+ こういう関数を用意してオレオレコーディングを楽しむのもアリと言えばアリです。
54
+ ```C++
55
+ #include <iostream>
56
+
57
+ namespace py_like {
58
+ void print() {
59
+ std::cout << "\n";
60
+ }
61
+
62
+ template <typename First, typename... Rest>
63
+ void print(const First& f, const Rest&... r) {
64
+ std::cout << f << " ";
65
+ print(r...);
66
+ }
67
+ }
68
+
69
+ int main() {
70
+ py_like::print(1, 2, 3);
71
+ }
72
+ ```
73
+
74
+ **実行結果** [Wandbox](https://wandbox.org/permlink/pteSBzNz3tJeTC2L)
75
+ ```plain
76
+ 1 2 3
77
+ ```

1

追記

2018/11/11 15:49

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -1,2 +1,46 @@
1
1
  タイポです。
2
- `heap[heap_size] == key;` ⇒ `heap[heap_size] = key;`
2
+ `heap[heap_size] == key;` ⇒ `heap[heap_size] = key;`
3
+
4
+ 追記
5
+ ---
6
+ 回答があまりに端的になったので、他にも気になったことをつらつら書きます。
7
+
8
+ **マクロの使い方**
9
+ マクロでしかできないことは、あまり多くありません。
10
+ 他の方法で充分且つシンプルに代替できるときはそれを利用してください。
11
+ ```C++
12
+ template<typename T>
13
+ void print(const T& arg) {
14
+ std::cout << arg << "\n";
15
+ }
16
+ ```
17
+
18
+ また、どうしてもマクロを使いたいときは、UPPER_SNAIL_CASEで命名するのが一般的です。
19
+ ```C++
20
+ #define PRINT(x) \
21
+ std::cout << x << "\n"
22
+ ```
23
+
24
+ **メンバ変数の取り扱い**
25
+ 可視性は可能な限りprivateにすべきです。
26
+ 剥き出しのメンバ変数は、グローバル変数と同じように取りまわせてしまうからです。
27
+
28
+ **利用するヘッダ**
29
+ これに関しては個人的な好みが大いにありますが、
30
+ bits/g++.hではなく、必要な標準ヘッダをインクルードした方がシンプルかと。
31
+
32
+ 今回の場合 string と iostream だけで済みそうです。
33
+
34
+ **インクリメントを使いこなす**
35
+ ```C++
36
+ ++heap_size;
37
+ heap[heap_size] = key;
38
+ ```
39
+
40
+ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
41
+ ```C++
42
+ heap[++heap_size] = key;
43
+ ```
44
+
45
+ これも好みの問題ですが、
46
+ せっかく単項インクリメントが用意されているのでその恩恵に預かっても良いのかな、と。