2016-01-15 13 views
7

だから私はthis article about type erasureを読んでいた。しかし、その記事のコードは、例えば、部分的に間違っているようだ:C++でタイプ消去とは何ですか?

void pullTheString() 
{ 
    MyAnimal *animals[] = 
    { 
     new AnimalWrapper(Cow()), /* oO , isn't template argument missing? */ 
     .... 
    }; 
} 

続い

template <typename T> 
class AnimalWrapper : public MyAnimal 
{ 
    const T &m_animal; 

public: 
    AnimalWrapper(const T &animal) 
     : m_animal(animal) 
    { } 

    const char *see() const { return m_animal.see(); } 
    const char *say() const { return m_animal.say(); } 
}; 

これらのミスは、記事内の任意のさらなる読んでから私をがっかり。

とにかく;誰でも簡単な例で、C++でどんなタイプの消去を教えてもらえますか?

std::functionがどのように機能するのかを知りたいと思っていましたが、私の周りに頭を浮かべることはできませんでした。

+0

:http://stackoverflow.com/questions/5450159/type-erasure-techniques – NathanOliver

+1

あなたのいずれかが ''を渡し、または 'T'を推定し、 'を'渡す関数を使用する必要があります。つまり、 'newAnimalWrapper'を' WrapAnimal'に置き換えます。これは、 'newAnimalWrapper'を' WrapAnimal'に置き換えます。 – Yakk

+0

@ NathanOliverその質問では、OPはすでに消去タイプの基本概念を知っています。 –

答えて

10

はここでアクションで型消去の非常に単純な例です:

// Type erasure side of things 

class TypeErasedHolder 
{ 
    struct TypeKeeperBase 
    { 
    virtual ~TypeKeeperBase() {} 
    }; 

    template <class ErasedType> 
    struct TypeKeeper : TypeKeeperBase 
    { 
    ErasedType storedObject; 

    TypeKeeper(ErasedType&& object) : storedObject(std::move(object)) {} 
    }; 

    std::unique_ptr<TypeKeeperBase> held; 

public: 
    template <class ErasedType> 
    TypeErasedHolder(ErasedType objectToStore) : held(new TypeKeeper<ErasedType>(std::move(objectToStore))) 
    {} 
}; 

// Client code side of things 

struct A 
{ 
    ~A() { std::cout << "Destroyed an A\n"; } 
}; 

struct B 
{ 
    ~B() { std::cout << "Destroyed a B\n"; } 
}; 

int main() 
{ 
    TypeErasedHolder holders[] = { A(), A(), B(), A() }; 
} 

[Live example]

あなたが見ることができるように、TypeErasedHolderは、任意の型のオブジェクトを格納し、それらを正しく破棄させることができます。重要な点は、(1)でサポートされているタイプに制限を課すものではないことです。たとえば、共通のベースから派生する必要はありません。もちろん、移動可能除い


(1)。 /デュープ関連

+0

なぜ、 '' TypeErasedHolder''のコンストラクタ引数と '' std :: forward''の '' && ''(汎用参照(?))を '' TypeKeeper' '? (ここで理解しようとすると、コピーを取って元のオブジェクトを移動するのではなく、そのコピーから移動しているように見えます) –

+1

@JonasWielickiこの例の「非常に単純な」側面を維持します。転送参照を使用するには、 'TypeKeeper'などのテンプレート引数に' std :: remove_reference'を使用する必要があります。 – Angew

+0

清算してくれてありがとう! –

関連する問題