此代码基于boost::any。它使用类型擦除来存储任意值并禁止分配给它。我去掉了铸造机械,使它更容易看清。
也许你可以在包装方面取得一些成功,boost::any
而不是完全重新实现,但我不确定这一点,你需要对演员表有所照顾。
它还禁止复制和移动,因为我懒得处理这个,但你的完整实现应该有它。
您还想给它起一个更有意义的名称。
#include <typeinfo>
#include <iostream>
class reassign_any {
public:
reassign_any() : content_(nullptr) {}
template <typename T>
reassign_any(const T& x) : content_(new holder<T>(x)) {}
~reassign_any() {
// no need to check for null
delete content_;
}
reassign_any(const reassign_any&) = delete;
reassign_any& operator=(const reassign_any&) = delete;
reassign_any(reassign_any&&) = delete;
reassign_any& operator=(reassign_any&&) = delete;
bool empty() const { return !content_; }
template <typename T>
bool set(const T& t) {
if(content_) {
// check for type equality of held value and value about to be
// set
if(content_->type() == typeid(T)) {
delete content_;
content_ = new holder<T>(t);
return true;
} else {
return false;
}
} else {
// just create
content_ = new holder<T>(t);
return true;
}
}
template <typename T>
T* get() {
return content_->type() == typeid(T)
? &static_cast<holder<T>*>(content_)->held
: 0;
}
private:
class placeholder
{
public: // structors
virtual ~placeholder()
{
}
virtual const std::type_info & type() const = 0;
};
template<typename ValueType>
class holder : public placeholder
{
public: // structors
holder(const ValueType & value)
: held(value)
{
}
virtual const std::type_info & type() const
{
return typeid(ValueType);
}
public: // representation
ValueType held;
private: // intentionally left unimplemented
holder & operator=(const holder &);
};
private:
placeholder* content_;
};
int main()
{
reassign_any x;
x.set(3);
if(x.get<int>())
std::cout << "int set" << std::endl;
if(x.set(3.f)) {
std::cout << "this shouldn't be printed" << std::endl;
} else {
std::cout << "this should be printed" << std::endl;
}
if(x.set(23)) {
std::cout << "this should be printed" << std::endl;
} else {
std::cout << "this shouldn't be printed" << std::endl;
}
return 0;
}
不相关的说明:Boost.TypeErasure 最近接受了审查。我真的很想尝试用它来实现这个版本的 any 至少看看实现是否允许它。