64,668
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <string>
class any
{
public:
//Representation and basic construction of a generalized union type.
any(): content(0)
{
}
~any()
{
delete content;
}
const std::type_info &type_info() const
{
return content ? content->type_info() : typeid(void);
}
//INWARD CONVERSIONS
any(const any &other) : content(other.content ? other.content->clone() : 0)
{
}
template<typename value_type>
any(const value_type &value) : content(new holder<value_type>(value))
{
}
any &swap(any &rhs)
{
std::swap(content, rhs.content);
return *this;
}
any &operator=(const any &rhs)
{
return swap(any(rhs));
}
template<typename value_type>
any &operator=(const value_type &rhs)
{
return swap(any(rhs));
}
//OUTWARD CONVERSIONS
operator const void *() const
{
return content;
}
template<typename value_type>
bool copy_to(value_type &value) const
{
const value_type *copyable = to_ptr<value_type>();
if(copyable)
value = *copyable;
return copyable;
}
template<typename value_type>
const value_type *to_ptr() const
{
return type_info() == typeid(value_type)?
&static_cast<holder<value_type> *>(content)->held : 0;
}
private:
class placeholder
{
public:
virtual ~placeholder()
{
}
virtual const std::type_info & type_info() const = 0;
virtual placeholder *clone() const = 0;
};
template<typename value_type>
class holder : public placeholder
{
public:
holder(const value_type &value) : held(value)
{
}
virtual const std::type_info &type_info() const
{
return typeid(value_type);
}
virtual placeholder *clone() const
{
return new holder(held);
}
const value_type held;
};
placeholder *content;
};
template<typename value_type>
value_type any_cast(const any &operand)
{
const value_type *result = operand.to_ptr<value_type>();
//return result ? *result : throw std::bad_cast();
if (result)
return *result;
throw std::bad_cast();
}
int main(int argc, char* argv[])
{
any i_a = 3;
int i_b = any_cast<int>(i_a);
std::cout<<i_a<<"\t"<<i_b<<std::endl;
any s_a = std::string("demo");
std::string s_b = any_cast<std::string>(s_a);
std::cout<<s_a<<"\t"<<s_b<<std::endl;
return 0;
}