回答編集履歴

6

追記

2018/11/12 06:30

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -205,3 +205,15 @@
205
205
 
206
206
 
207
207
  [PRE00-C. 関数形式マクロよりもインライン関数やスタティック関数を使う](https://www.jpcert.or.jp/sc-rules/c-pre00-c.html)
208
+
209
+ なお、リンク先で紹介されている『例外』も、C++ならある程度代替可能です。
210
+
211
+ 0. PRE00-C-EX1(ローカル関数) ⇒ ラムダでクロージャを作れば良い
212
+
213
+ 0. PRE00-C-EX3(コンパイル時定数) ⇒ constexpr
214
+
215
+ 0. PRE00-C-EX4(型総称関数) ⇒ template
216
+
217
+
218
+
219
+ トークンの連結は、C++でもできそうに無いですが。

5

追記

2018/11/12 06:30

投稿

LouiS0616
LouiS0616

スコア35660

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

4

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

2018/11/12 06:21

投稿

LouiS0616
LouiS0616

スコア35660

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

3

追記

2018/11/12 06:08

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -151,3 +151,53 @@
151
151
  1 2 3
152
152
 
153
153
  ```
154
+
155
+
156
+
157
+ さらなるおまけ
158
+
159
+ ---
160
+
161
+ マクロを使うと、見づらさ以上の弊害があります。
162
+
163
+ 競プロ界隈ではしばしば使われるようですが、リスクは理解しておきたいものです。
164
+
165
+ ```C++
166
+
167
+ #include <iostream>
168
+
169
+
170
+
171
+ #define PRINT_1(x) std::cout << x << "\n";
172
+
173
+ #define PRINT_2(x) std::cout << (x) << "\n";
174
+
175
+
176
+
177
+ template<typename T>
178
+
179
+ void print(const T& arg) {
180
+
181
+ std::cout << arg << "\n";
182
+
183
+ }
184
+
185
+
186
+
187
+ int main() {
188
+
189
+ print (1 << 2); // 4
190
+
191
+ PRINT_1(1 << 2); // 12
192
+
193
+ PRINT_2(1 << 2); // 4
194
+
195
+ }
196
+
197
+ ```
198
+
199
+
200
+
201
+ `1 << 2`という文字列のまま扱われるのが厄介なんですよね、マクロの場合。
202
+
203
+ 片っ端から括弧を付ければ良いわけですが、デメリットがメリットに釣り合いません。

2

修正

2018/11/12 06:05

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  #define PRINT(x) \
40
40
 
41
- std::cout << x << "\n"
41
+ std::cout << (x) << "\n"
42
42
 
43
43
  ```
44
44
 
@@ -89,3 +89,65 @@
89
89
  これも好みの問題ですが、
90
90
 
91
91
  せっかく単項インクリメントが用意されているのでその恩恵に預かっても良いのかな、と。
92
+
93
+
94
+
95
+ **範囲外へのアクセス**
96
+
97
+ 他言語と比べて、C/C++での生配列への範囲外アクセスは感知しづらいです。
98
+
99
+ 範囲内であるか前以て判定する処理を書いておけば安心です。
100
+
101
+
102
+
103
+ ---
104
+
105
+ こういう関数を用意してオレオレコーディングを楽しむのもアリと言えばアリです。
106
+
107
+ ```C++
108
+
109
+ #include <iostream>
110
+
111
+
112
+
113
+ namespace py_like {
114
+
115
+ void print() {
116
+
117
+ std::cout << "\n";
118
+
119
+ }
120
+
121
+
122
+
123
+ template <typename First, typename... Rest>
124
+
125
+ void print(const First& f, const Rest&... r) {
126
+
127
+ std::cout << f << " ";
128
+
129
+ print(r...);
130
+
131
+ }
132
+
133
+ }
134
+
135
+
136
+
137
+ int main() {
138
+
139
+ py_like::print(1, 2, 3);
140
+
141
+ }
142
+
143
+ ```
144
+
145
+
146
+
147
+ **実行結果** [Wandbox](https://wandbox.org/permlink/pteSBzNz3tJeTC2L)
148
+
149
+ ```plain
150
+
151
+ 1 2 3
152
+
153
+ ```

1

追記

2018/11/11 15:49

投稿

LouiS0616
LouiS0616

スコア35660

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