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

質問編集履歴

1

追記4。

2020/03/21 05:19

投稿

Paalon
Paalon

スコア266

title CHANGED
File without changes
body CHANGED
@@ -182,4 +182,69 @@
182
182
  1. 一般的に C++ で想定されている部分型ポリモルフィズムの実現方法がメンバ関数としてのシングルディスパッチであり、それではマルチディスパッチは実現できないということ。
183
183
  2. C++ でマルチディスパッチを実現しようとすればできるが、パラメトリックポリモルフィズムが絡んだとき、つまり、配列などのコンテナの要素の型に関して部分型ポリモルフィズムをするときには、`std::variant` を使ったようなコードを書く必要があり、そのあたりのコードがパフォーマンス的によろしくない、もしくは自動的に subtyping された `std::variant` 的なものが作れないためにコードが煩雑であり、現実的でない?どちらにせよ、あまり一般的に(まだ?)使われていない。
184
184
 
185
- ということなんでしょうか?
185
+ ということなんでしょうか?
186
+
187
+ ---
188
+
189
+ ** 追記4 **:
190
+
191
+ Julia だと確かに以下のように `if ... else ..` を使ったものでもそうでなくてもコンパイルされた機械語は全く同じです。
192
+
193
+ ```julia
194
+ mutable struct Dog end
195
+ mutable struct Cat end
196
+ foo(::Dog) = println("Dog")
197
+ foo(::Cat) = println("Cat")
198
+
199
+ t = 0
200
+ a = if t == 0 Dog() else Cat() end
201
+ b = Dog()
202
+
203
+ @code_native foo(a)
204
+ @code_native foo(b)
205
+ ```
206
+
207
+ ただ C++ でも等価な機械語になるかどうかは分かりませんが、`if ... else ...` を使ったコードは以下のように書けますよね?
208
+
209
+ ```cpp
210
+ #include <iostream>
211
+ #include <variant>
212
+
213
+ struct Dog {};
214
+ struct Cat {};
215
+ using DogOrCat = std::variant<Dog, Cat>;
216
+
217
+ auto foo(Dog const &) {
218
+ std::cout << "Dog" << std::endl;
219
+ }
220
+ auto foo(Cat const &) {
221
+ std::cout << "Cat" << std::endl;
222
+ }
223
+
224
+ int main() {
225
+ auto t = 0;
226
+ auto a = [&] () {
227
+ if (t == 0) {
228
+ return DogOrCat(Dog());
229
+ }
230
+ return DogOrCat(Cat());
231
+ } ();
232
+ std::visit(
233
+ [] (auto const & x) {
234
+ foo(x);
235
+ },
236
+ a
237
+ );
238
+ }
239
+ ```
240
+
241
+ 仮想関数テーブルによりシングルディスパッチが可能であることは理解しています。質問はそこではなくて、
242
+
243
+ 1. 今の例のような `std::variant`, もしくはもっと洗練された何かを使って多重ディスパッチを実現することが可能ではないか?
244
+ 2. この実装では 明示的に `DogOrCat` を作成しているが、`Animal` を `Dog` と `Cat` が継承しているときに、自動的にそれに対応する `std::variant` を生成できるのか?
245
+ 3. この実装では長ったらしい表現(`std::variant` や `std::visit`)を書かなければいけないが、避けることはできないのか?
246
+ 4. この実装のポリモルフィズムは実践的に問題となる点(パフォーマンスやバグ、表現力が不十分であるなど)を抱えているのか?
247
+ 5. 上記の点が全てクリアされているならば、Julia と同じぐらいの表現力で多重ディスパッチ可能であると言えるのではないか?
248
+ 6. そうであるならばもとの Julia の文章はこの方式によるポリモルフィズムを想定していない or 不適切であるということになるのではないか?
249
+
250
+ ということです。