質問編集履歴
1
追記4。
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
|
+
ということです。
|