C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: TypeErasure(型消去)


(過去ログ 56 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■31505 / inTopicNo.1)  TypeErasure(型消去)
  
□投稿者/ falcon (1回)-(2009/01/22(Thu) 23:48:33)

分類:[C/C++] 

http://www.artima.com/cppsource/type_erasure2.html

にTypeErasure(型消去)のサンプルソースがあるのですが、
ソースを追うことはできるのですが、何がどう型消去なのか
わかりません。教えてください。

なぜ、placeholder が必要なのでしょうか?
placeholder がなくても良さそうに思えます。

適当ですが、、以下の用な実装では型消去と言わないのでしょうか?

template<class ValueType >
class Any
{
  public:
    Any(ValueType& value);
    Any(const Any& other);
    Any& operator=(const Any& other);

    // その他いろいろ

  private:
    ValueType content;
};

placeholder を使う実装が一番ポピュラーなのでしょうか?

引用返信 編集キー/
■31509 / inTopicNo.2)  Re[1]: TypeErasure(型消去)
□投稿者/ yu-yu (4回)-(2009/01/23(Fri) 01:04:13)
> なぜ、placeholder が必要なのでしょうか?
> placeholder がなくても良さそうに思えます。
上記URLのソースを見たのですが、placeholderが基底クラスとして存在しないと
色々な型をanyクラスに代入することができないので必要なんじゃないでしょうか?

ちなみに、
>template
>any(ValueType const & value) : content(new holder(value)) {}
こうなって見えますが正しくはこうですね。
template <typename ValueType>
any(ValueType const & value) : content(new holder<ValueType>(value)) {}
#htmlのソースを表示したらちゃんと書いてありましたけど。

上記サイトのanyを使うと以下のようなことができます。
any hoge = 1;         // int型
std::string s("abc");
hoge = s;             // string型を入れてもエラーにならない

> 適当ですが、、以下の用な実装では型消去と言わないのでしょうか?
この例だとanyは宣言時に型を指定しなければ使えないので型消去ではないと思います。
Any<int> hoge = 1;
std::string s("abc");
hoge = s;             // string型はエラー

引用返信 編集キー/
■31512 / inTopicNo.3)  Re[1]: TypeErasure(型消去)
□投稿者/ アキラ (152回)-(2009/01/23(Fri) 01:48:14)
アキラ さんの Web サイト
No31505 (falcon さん) に返信

Boost.Anyで使われてるのは、非テンプレート基本クラスとテンプレート派生クラスを使用したType Erasureですね。
Boost.Anyはクラステンプレートではありませんが、あらゆる型をメンバとして持つことができ、
メンバとして持ってるあらゆる型の値を取り出すこともできます。

class any {
    ??? value_;
public:
    template <class T>
    any(const T& value);
};

このとき、メンバの型は何にすればいいんだー、というときにType Erasureという手法がよく使われます。

非テンプレート基本クラスとテンプレート派生クラスを使用する
タイプのType Erasureは以下のような感じで行います。

class base {};

template <class T>
class derived : public base {};

こういうのを用意しておくと、多態性を利用してderivedが持つ型情報Tをbaseに隠すことができます。

class any {
    base* p;
public:
    template <class T>
    any(const T&)
    {
        p = new derived<T>();
    }
};

この方法でのType ErasureはBoostでよく使われています。

引用返信 編集キー/
■31517 / inTopicNo.4)  Re[2]: TypeErasure(型消去)
□投稿者/ falcon (3回)-(2009/01/23(Fri) 09:29:36)
>この例だとanyは宣言時に型を指定しなければ使えないので型消去ではないと思います

使う側に型を意識(指定)させる必要がないから型消去なんですね?

その為に、型を保持するクラス placeholder を用意して、Anyクラスにplaceholderを
持たせて、Anyクラスのテンプレートコンストラクタで、holder(placeholder) を new する時に
型を指定してあげるという寸法ですね。

なんか、すごく分かった気がします・・・ありがとうございます。

#プレビューから送信すると投稿できないのですが・・・
引用返信 編集キー/
■31522 / inTopicNo.5)  Re[3]: TypeErasure(型消去)
□投稿者/ アキラ (153回)-(2009/01/23(Fri) 11:16:44)
アキラ さんの Web サイト
No31517 (falcon さん) に返信

> 使う側に型を意識(指定)させる必要がないから型消去なんですね?

型安全を保ったまま型情報を消去するのがType Erasureでしょう。
> 多態性を利用してderivedが持つ型情報Tをbaseに隠すことができます。

使う側に型を意識させないというだけなら関数テンプレートの型推論で十分です。
引用返信 編集キー/
■31525 / inTopicNo.6)  Re[4]: TypeErasure(型消去)
□投稿者/ falcon (5回)-(2009/01/23(Fri) 11:42:52)
No31522 (アキラ さん) に返信
> ■No31517 (falcon さん) に返信
>
>>使う側に型を意識(指定)させる必要がないから型消去なんですね?
> 型安全を保ったまま型情報を消去するのがType Erasureでしょう。

Anyクラスのメンバ変数をplaceholderに隠して、実際の型を分からなくして、Anyクラスから消す。ってことですかね?
pimpleが実装を隠すなら、TypeErasureは型を隠すってところですか?

# 自分の言葉して、その解釈が間違ってないかの確認です・・・

引用返信 編集キー/
■31527 / inTopicNo.7)  Re[5]: TypeErasure(型消去)
□投稿者/ アキラ (154回)-(2009/01/23(Fri) 11:49:19)
アキラ さんの Web サイト
No31525 (falcon さん) に返信

> Anyクラスのメンバ変数をplaceholderに隠して、実際の型を分からなくして、Anyクラスから消す。ってことですかね?
> pimpleが実装を隠すなら、TypeErasureは型を隠すってところですか?

そうですね。
その考えで間違ってないと思います。
引用返信 編集キー/
■31571 / inTopicNo.8)  Re[5]: TypeErasure(型消去)
□投稿者/ yu-yu (5回)-(2009/01/24(Sat) 01:27:26)
No31525 (falcon さん) に返信
返信がすぐにできなくてすみませんでした。

> pimpleが実装を隠すなら、TypeErasureは型を隠すってところですか?
とても良い表現ですね。

それにしてもアキラさんの説明はわかりやすいですね。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -