2012-03-01 3 views
2

からタイプを推測:その関数Workを想定は、次の例を考えボイドポインタ

class MyContainer { 
    std::vector<void *> v; 
public: 
    void Put(void *x) { v.push_back(x);} 
    void* Get(int index) { return v[index];} 
}; 

void Work (MyContainer& c) { 
    // cast_to_type(c.Get(0)); 
} 

int main() { 
    int x = 1; 
    double y = 2.0; 
    MyContainer c; 
    c.Put(&x); 
    c.Put(&y); 

    Work(c); 

    return 0; 
} 

をベクトルポインタが指すようにオブジェクトについて何も知りません。また、継承はオプションではなく、指し示されたオブジェクトのタイプは任意であることができます(無限のタイプがあります)。

MyContainer::Get関数が返すvoidポインタだけを使用して型を推論することはできますか?キャスト、テンプレート、typeidオペレータの任意の組み合わせを使用してこれを行うことはできますか?

+6

短い回答:いいえ。 –

+0

テンプレートを使用してオブジェクトをラップし、ラップされたオブジェクトにポインタを配置するとどうなりますか?テンプレートを使用して、何らかの形で情報を保存することはできますか? – Diggy

+0

@Diggy:直接ではありませんが、このラッパーを使用して継承を適用​​できるようになりました。 ['boost :: any'](http://www.boost.org/doc/libs/1_49_0/doc/html/any.html)を参照してください。 – Xeo

答えて

9

いいえ、void*には、まったく関連する情報はありません。ポインタをvoid*にキャストすると、完全に型を失います。継承の場合など、異なるコンテナを同じコンテナに格納する別の方法を見つける必要があります。

はまた、このような何かを行うことができます:

class MyContainer { 
    struct cont { 
     void* ptr; 
     type_info* ti; // pointer, not reference, so this struct can be copied 
    }; 

    std::vector<cont> v; 

public: 
    template<typename T> 
    void Put(T* x) { 
     v.push_back({ x, &typeid(T) }); 
    } 

    // do whatever you want with Get using *v[x].ti 
}; 

int x = 1; 
double y = 2.0; 
MyContainer c; 
c.Put(&x); 
c.Put(&y); 

Work(c); 

しかし、私はあなたがやろうとしているものを知らずになりますどのように多くの助けを知りません。 boost::anyのような少し先進的なものに頼らなければならないかもしれません。

+0

あなたは私の編集よりも速いです:)。継承が不可能な場合はどうでしょうか? – Diggy

+0

@Diggy私の編集を参照 –

+0

残念ながら、type_infoを使用して、無効なポインタを適切な型に再作成することはできません。 [Typecasting_with_type_info](http://stackoverflow.com/questions/4972795/typecasting-with-type-in​​fo)を参照してください。これはまだ私の質問に対する解決策ではありません。 – Diggy

関連する問題