在这个程序中,我使用typeid来检查对象的派生类型:
#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 :(得分:6)
使用typeid
时,它可以应用于表达式或类型。当应用于某种类型时,您可以:
引用表示类型类型的std :: type_info对象。如果输入 是一个引用类型,结果引用一个std :: type_info对象 表示引用的类型。
http://en.cppreference.com/w/cpp/language/typeid。因此,无论您是否使用该引用,它都没有任何区别。同样的消息来源继续说:
无法保证同一个stid :: type_info实例将在同一个类型表达式的所有评估中引用 type,尽管那些type_info对象的std :: type_info :: hash_code 与std :: type_index相同。
这意味着将&typeid(impl)
与其他内容进行比较,即使对象具有相同的动态类型,也可能返回false。因此,比较他们的地址并不是一个好的选择。您应该直接比较对象本身,即只需从双方移除&
运算符,因为std::type_info
(由typeid
返回)已定义operator==
。