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

回答編集履歴

5

update

2021/12/23 08:22

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -35,4 +35,4 @@
35
35
 
36
36
  ~~C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。~~
37
37
 
38
- 追記:`&&`, `||`論理演算子オーバーロードではオペランド評価順保証(左→右)はあるもの、オペランドの短絡評価は行われません。例えば`a && b`は`a.operator&&(b)`と展開されるため、短絡評価は技術的に実現不可能でした。
38
+ 追記:`&&`, `||`論理演算子オーバーロードではオペランドの短絡評価は行われません。例えば`a && b`は`a.operator&&(b)`または`operator&&(a, b)`評価されるため、短絡評価は技術的に実現不可能でした。

4

短絡評価は不可能

2021/12/23 08:22

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -33,4 +33,6 @@
33
33
  (おまけ情報です)
34
34
  > もし、論理演算子をオーバーロードする必用が在る場合でも「&&」「||」は短絡評価ができなくなるため危険です
35
35
 
36
- C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。
36
+ ~~C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。~~
37
+
38
+ 追記:`&&`, `||`論理演算子オーバーロードではオペランド評価順保証(左→右)はあるものの、オペランドの短絡評価は行われません。例えば`a && b`は`a.operator&&(b)`と展開されるため、短絡評価は技術的に実現不可能でした。

3

appendix

2021/12/23 08:17

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -27,4 +27,10 @@
27
27
  [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)
28
28
  > Bottom line: don’t confuse your users.
29
29
  >
30
- > 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.
30
+ > 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.
31
+
32
+ ---
33
+ (おまけ情報です)
34
+ > もし、論理演算子をオーバーロードする必用が在る場合でも「&&」「||」は短絡評価ができなくなるため危険です
35
+
36
+ C++11時点(かつC++14までの)仕様では認識通りです。C++17では「`&&`, `||`論理演算子オーバーロードでも短絡評価が保証される」ように[言語仕様が改善されました](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)。とはいえ、C++コンパイラがどのように振舞うかはまだ微妙ですので、質問文中の認識でいたほうが安全だと思います。

2

update

2018/12/28 04:28

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -17,4 +17,14 @@
17
17
  * C++03の頃は`basic_ios::operator void*`ユーザ変換関数が提供されており、`if (s)`, `if (!s)` のいずれの書き方もできるようになりました。
18
18
  * C++11で言語仕様そのものが拡張され、 `explicit operator bool()` という表記が許されるようになりました。機能的には `operator void*`/`operator!` 両方をカバーし、かつプログラマの意図しない暗黙変換が起きるリスクも回避されます。
19
19
  * 一方で `operator void*` は[プログラマを混乱させる恐れがあった](http://d.hatena.ne.jp/yohhoy/20120406/p1)ため、このタイミングで削除されています。
20
- * `std::shared_ptr` はC++11で初めて標準ライブラリ入りしたため、最初から `explicit operator bool()` のみを提供すると考えられます。
20
+ * `std::shared_ptr` はC++11で初めて標準ライブラリ入りしたため、最初から `explicit operator bool()` のみを提供すると考えられます。
21
+
22
+ ---
23
+ > 自分でクラスを作るとき、!のオーバーロードを行うか否か?の指針が知りたいです。
24
+
25
+ `!`に限らず、演算子オーバーロードの提供有無は慎重に設計すべきです。ISO C++公式FAQ(下記)やC++ Core Guideline [C.over: Overloading and overloaded operators](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-overload) もご参考にどうぞ。
26
+
27
+ [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)
28
+ > Bottom line: don’t confuse your users.
29
+ >
30
+ > 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

2018/12/28 04:22

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  > 多くの場合、 explicit operator bool() のみがあれば大丈夫のような気がするのですが、あえて 否定演算子のオーバーロードをする積極的な理由は何なのでしょうか?
2
2
 
3
- 私も質問者myoonさん、catsforepawさんと同意見です。ごく一部の特殊なユースケースを除いて、否定演算子(`operator!`)オーバーロードを行うべでないと考えます。
3
+ 私も質問者myoonさん、catsforepawさんと同意見です。ごく一部の特殊なユースケースを除いて、否定演算子(`operator!`)オーバーロードでないと考えます。
4
4
 
5
5
  あえて演算子オーバーロードの意味があるとすれば;
6
6
 
@@ -15,6 +15,6 @@
15
15
 
16
16
  * 古代のC++言語では`basic_ios::operator!`をオーバーロードする以外に、IOストリームを真偽値に変換する手段がありませんでした。つまり`if (!s)`のような否定形しか記述できなかったようです。
17
17
  * C++03の頃は`basic_ios::operator void*`ユーザ変換関数が提供されており、`if (s)`, `if (!s)` のいずれの書き方もできるようになりました。
18
- * C++11で初めて `explicit operator bool()` という書き方が許されるようになりました。機能的には `operator void*`/`operator!` 両方をカバーしており、かつプログラマの意図しない暗黙
18
+ * C++11で言語仕様そのものが拡張され、 `explicit operator bool()` という表記が許されるようになりました。機能的には `operator void*`/`operator!` 両方をカバーし、かつプログラマの意図しない暗黙変換が起きるリスクも回避されます。
19
19
  * 一方で `operator void*` は[プログラマを混乱させる恐れがあった](http://d.hatena.ne.jp/yohhoy/20120406/p1)ため、このタイミングで削除されています。
20
20
  * `std::shared_ptr` はC++11で初めて標準ライブラリ入りしたため、最初から `explicit operator bool()` のみを提供すると考えられます。