回答編集履歴
5
update
test
CHANGED
@@ -72,4 +72,4 @@
|
|
72
72
|
|
73
73
|
|
74
74
|
|
75
|
-
追記:`&&`, `||`論理演算子オーバーロードではオペランド
|
75
|
+
追記:`&&`, `||`論理演算子オーバーロードではオペランドの短絡評価は行われません。例えば`a && b`は`a.operator&&(b)`または`operator&&(a, b)`と評価されるため、短絡評価は技術的に実現不可能でした。
|
4
短絡評価は不可能
test
CHANGED
@@ -68,4 +68,8 @@
|
|
68
68
|
|
69
69
|
|
70
70
|
|
71
|
-
|
71
|
+
~~C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。~~
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
追記:`&&`, `||`論理演算子オーバーロードではオペランド評価順保証(左→右)はあるものの、オペランドの短絡評価は行われません。例えば`a && b`は`a.operator&&(b)`と展開されるため、短絡評価は技術的に実現不可能でした。
|
3
appendix
test
CHANGED
@@ -57,3 +57,15 @@
|
|
57
57
|
>
|
58
58
|
|
59
59
|
> Remember the purpose of operator overloading: to reduce the cost and defect rate in code that uses your class. If you create operators that confuse your users (because they’re cool, because they make the code faster, because you need to prove to yourself that you can do it; doesn’t really matter why), you’ve violated the whole reason for using operator overloading in the first place.
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
---
|
64
|
+
|
65
|
+
(おまけ情報です)
|
66
|
+
|
67
|
+
> もし、論理演算子をオーバーロードする必用が在る場合でも「&&」「||」は短絡評価ができなくなるため危険です
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。
|
2
update
test
CHANGED
@@ -37,3 +37,23 @@
|
|
37
37
|
* 一方で `operator void*` は[プログラマを混乱させる恐れがあった](http://d.hatena.ne.jp/yohhoy/20120406/p1)ため、このタイミングで削除されています。
|
38
38
|
|
39
39
|
* `std::shared_ptr` はC++11で初めて標準ライブラリ入りしたため、最初から `explicit operator bool()` のみを提供すると考えられます。
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
---
|
44
|
+
|
45
|
+
> 自分でクラスを作るとき、!のオーバーロードを行うか否か?の指針が知りたいです。
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
`!`に限らず、演算子オーバーロードの提供有無は慎重に設計すべきです。ISO C++公式FAQ(下記)やC++ Core Guideline [C.over: Overloading and overloaded operators](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-overload) もご参考にどうぞ。
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
[The previous FAQs tell me which operators I can override; but which operators should I override?](https://isocpp.org/wiki/faq/operator-overloading#law-of-least-surprise-op-ov)
|
54
|
+
|
55
|
+
> Bottom line: don’t confuse your users.
|
56
|
+
|
57
|
+
>
|
58
|
+
|
59
|
+
> Remember the purpose of operator overloading: to reduce the cost and defect rate in code that uses your class. If you create operators that confuse your users (because they’re cool, because they make the code faster, because you need to prove to yourself that you can do it; doesn’t really matter why), you’ve violated the whole reason for using operator overloading in the first place.
|
1
refinement
test
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
-
私も質問者myoonさん、catsforepawさんと同意見です。ごく一部の特殊なユースケースを除いて、否定演算子(`operator!`)
|
5
|
+
私も質問者myoonさん、catsforepawさんと同意見です。ごく一部の特殊なユースケースを除いて、否定演算子(`operator!`)はオーバーロードすべきでないと考えます。
|
6
6
|
|
7
7
|
|
8
8
|
|
@@ -32,7 +32,7 @@
|
|
32
32
|
|
33
33
|
* C++03の頃は`basic_ios::operator void*`ユーザ変換関数が提供されており、`if (s)`, `if (!s)` のいずれの書き方もできるようになりました。
|
34
34
|
|
35
|
-
* C++11で
|
35
|
+
* C++11で言語仕様そのものが拡張され、 `explicit operator bool()` という表記が許されるようになりました。機能的には `operator void*`/`operator!` 両方をカバーし、かつプログラマの意図しない暗黙変換が起きるリスクも回避されます。
|
36
36
|
|
37
37
|
* 一方で `operator void*` は[プログラマを混乱させる恐れがあった](http://d.hatena.ne.jp/yohhoy/20120406/p1)ため、このタイミングで削除されています。
|
38
38
|
|