c++ 实现Variant,并可以拷贝操作
时间: 2024-03-19 15:45:03 浏览: 78
Variant 是一种可以存储不同类型数据的数据类型。在 C++ 中可以使用模板实现 Variant ,具体实现如下:
```cpp
#include <memory>
#include <type_traits>
class Variant {
public:
Variant() noexcept = default;
Variant(const Variant& other) {
if (other._data) {
other._data->copy_to(_data);
_type_info = other._type_info;
}
}
Variant& operator=(const Variant& other) {
if (other._data) {
other._data->copy_to(_data);
_type_info = other._type_info;
} else {
_data.reset();
_type_info = nullptr;
}
return *this;
}
template <typename T>
Variant(T&& value) {
_data = std::make_unique<Holder<std::decay_t<T>>>(std::forward<T>(value));
_type_info = &typeid(std::decay_t<T>);
}
template <typename T>
Variant& operator=(T&& value) {
if (_data) {
_data.reset();
}
_data = std::make_unique<Holder<std::decay_t<T>>>(std::forward<T>(value));
_type_info = &typeid(std::decay_t<T>);
return *this;
}
template <typename T>
const T& get() const {
if (_type_info && *_type_info == typeid(T)) {
return static_cast<Holder<T>*>(_data.get())->value;
}
throw std::bad_cast();
}
template <typename T>
T& get() {
if (_type_info && *_type_info == typeid(T)) {
return static_cast<Holder<T>*>(_data.get())->value;
}
throw std::bad_cast();
}
bool empty() const {
return !_data;
}
private:
class IHolder {
public:
virtual ~IHolder() = default;
virtual void copy_to(std::unique_ptr<IHolder>& other) const = 0;
};
template <typename T>
class Holder : public IHolder {
public:
template <typename U>
Holder(U&& value) : value(std::forward<U>(value)) {}
void copy_to(std::unique_ptr<IHolder>& other) const override {
other = std::make_unique<Holder<T>>(value);
}
T value;
};
std::unique_ptr<IHolder> _data;
const std::type_info* _type_info = nullptr;
};
```
该实现中,使用了一个 IHolder 抽象基类来表示存储的数据,Holder 类是 IHolder 的具体实现,包含了存储的数据和拷贝操作。在 Variant 中,使用一个 std::unique_ptr<IHolder> 类型的成员变量 _data 存储数据,_type_info 存储数据的类型信息。
实现中还包括了拷贝构造函数、拷贝赋值运算符,并且支持使用任何类型来构造 Variant ,使用 get() 方法来获取存储的数据,并且支持空 Variant 。
阅读全文