#include<memory>
#include<typeindex>
#include<type_traits>
#include<iostream>
#include<string>
using namespace std;
struct Any
{
Any():m_tpIndex(std::type_index(typeid(void))) {}
Any(const Any& other) :m_ptr(other.clone()), m_tpIndex(other.m_tpIndex) {}
Any( Any&& other) noexcept :m_ptr(std::move(other.m_ptr)), m_tpIndex(other.m_tpIndex) {}
//避免压制复制操作
template<typename U, typename = std::enable_if_t<std::negation_v<std::is_same<std::decay_t<U>, Any>> ,U> >
Any(U&& value) : m_ptr(new Derived< std::decay_t<U> >(std::forward<U>(value)) ), m_tpIndex(std::type_index(typeid(std::decay_t<U>))){}
bool has_value()
{
return bool(m_ptr);
}
template<typename U>
bool is()const
{
return m_tpIndex == std::type_index(typeid(U));
}
template<typename U>
U& AnyCast()
{
if (!is<U>())
{
std::cout << m_tpIndex.name()<< "can not cast to " << typeid(U).name() <<std::endl;
exit(-1);
}
auto derived = dynamic_cast<Derived<U>*>(m_ptr.get());
return derived->m_value;
}
Any& operator=(const Any& other)
{
if (m_ptr == other.m_ptr)
return *this;
m_ptr = other.clone();
m_tpIndex = other.m_tpIndex;
return *this;
}
private:
struct Base;
using BasePtr=std::unique_ptr<Base>;
struct Base
{
virtual ~Base(){};
virtual BasePtr clone() const = 0;
};
template<typename T>
struct Derived:public Base
{
template<typename U>
Derived(U&& value):m_value(std::forward<U>(value)){ }
BasePtr clone() const
{
return BasePtr(new Derived<T>(m_value));
}
T m_value;
};
BasePtr clone()const
{
if (m_ptr != nullptr)
return m_ptr->clone();
return nullptr;
}
BasePtr m_ptr;
std::type_index m_tpIndex;
};
int main()
{
Any n;
auto r = n.has_value();
string str("123");
n = str;
auto m=n.AnyCast<string>();
auto m2 = n.AnyCast<int>();
Any n1 = 1;
auto res=n1.is<int>();
return 0;
}
C++17类型擦除器 std::any实现示例
最新推荐文章于 2024-02-28 19:13:24 发布