2016-11-18 8 views
4

私は、オブジェクトの派生型をチェックするために型IDを使用します。比較型IDポインタ

#include <cstdint> 
#include <memory> 
#include <cassert> 
#include <string> 
#include <typeinfo> 

struct Wrap 
{ 
    explicit Wrap(int64_t id) : mImpl(new Impl<int64_t>(id)) {} 

    explicit Wrap(std::string id) : mImpl(new Impl<std::string>(std::move(id))) {}  

    bool isInt64() const 
    { 
     const ImplBase& impl = *mImpl; 
     return (&typeid(impl) == &typeid(const Impl<int64_t>)); 
    }  

    bool isString() const 
    { 
     const ImplBase& impl = *mImpl; 
     return &typeid(impl) == &typeid(const Impl<std::string>); 
    } 

private: 
    struct ImplBase 
    { 
     virtual ~ImplBase() {} 
    }; 

    template<typename T> 
    struct Impl : ImplBase 
    { 
     Impl(T value) : 
      mValue(std::move(value)) 
     { 
     } 

     T mValue; 
    }; 

    std::shared_ptr<const ImplBase> mImpl; 
}; 

int main() 
{ 
    Wrap r1(int64_t(1)); 
    assert(r1.isInt64()); 

    Wrap r2(std::string("s")); 
    assert(r2.isString()); 
} 

動作しているようですが、しかし、私は、これはすべてのプラットフォームで動作しない可能性があることを心配します。また、私は、私が使用する必要があるかはわからない:

比較機能で
typeid(const Impl<std::string>&) // with ref 

代わりの

typeid(const Impl<std::string>) // without ref 

上記のコードは正しいですか?そうでない場合は、どうすれば修正できますか?

+0

VTのtypeidフィールドに参照型が格納されるのはなぜですか? – Arunmu

+0

@Arunmu良い点は、私はそれを考慮していなかった。 – StackedCrooked

答えて

5

typeidを使用する場合は、式またはタイプのいずれかに適用できます。

タイプタイプを表すstd :: type_infoオブジェクトを参照してください。タイプ が参照タイプの場合、結果は参照されるタイプを表すstd :: type_infoオブジェクト を参照します。

http://en.cppreference.com/w/cpp/language/typeid。したがって、参照を使用するかどうかにかかわらず、何の違いもありません。同じソースが言うように行く:

同じSTDという保証はありません::インスタンスTYPE_INFOのstd :: TYPE_INFOものの、同じ タイプ上のtypeid式のすべての評価によって参照されます::これらのtype_infoオブジェクトのhash_code は、std :: type_indexと同じになります。 、何か他のものに&typeid(impl)を比較すると、オブジェクトが同じ動的な型を持っている場合でもfalseを返すことができることを意味し

。だから、彼らの住所を比較するのは良い選択ではありません。 std::type_info(返されたtypeid)のoperator==が定義されているため、オブジェクト自体を直接比較する必要があります。つまり、演算子&を両側から削除するだけです。