A simple implementation of 'any' type in c++11.
refer to cnblogs.com/qiconmos/p/3420095.html
| #include <memory> // for unique_ptr | |
| #include <utility> // for forward | |
| #include <typeindex> // for type_index | |
| //Any, refere to cnblogs.com/qiconmos/p/3420095.html, keyword: c++11 any | |
| class Any { | |
| struct Base; | |
| typedef std::unique_ptr<Base> BasePtr; | |
| struct Base { | |
| virtual ~Base() {} | |
| virtual BasePtr clone() const = 0; | |
| }; | |
| template <typename T> | |
| struct Derived : 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) return m_ptr->clone(); | |
| return nullptr; | |
| } | |
| BasePtr m_ptr; | |
| std::type_index m_tpIndex; | |
| public: | |
| Any(void) : m_tpIndex(std::type_index(typeid(void))) {} | |
| Any(const Any &a) : m_ptr(a.clone()), m_tpIndex(a.m_tpIndex) {} | |
| Any(Any &&a) : m_ptr(std::move(a.m_ptr)), m_tpIndex(a.m_tpIndex) {} | |
| template<typename U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type> | |
| Any(U && value) : m_ptr(new Derived<typename std::decay<U>::type>(std::forward<U>(value))), | |
| m_tpIndex(std::type_index(typeid(typename std::decay<U>::type))) | |
| { } | |
| bool isNull() const { return !bool(m_ptr); } | |
| bool isValid() const { return bool(m_ptr); } | |
| template <class U> bool is() const { | |
| return m_tpIndex == std::type_index(typeid(U)); | |
| } | |
| template <class U> | |
| U & cast() { | |
| if (!is<U>()) throw std::bad_cast(); | |
| auto derived = dynamic_cast<Derived<U>*>(m_ptr.get()); | |
| return derived->m_value; | |
| } | |
| Any & operator = (const Any & a) { | |
| if (m_ptr == a.m_ptr) return *this; | |
| m_ptr = a.clone(); | |
| m_tpIndex = a.m_tpIndex; | |
| return *this; | |
| } | |
| const char* typeName() const { return m_tpIndex.name(); } | |
| }; | |
| #include <string> | |
| #include <iostream> | |
| int main() { | |
| int int_aa = 11; | |
| std::string hello("hello"); | |
| Any aa(int_aa); | |
| Any bb(hello); | |
| Any cc(&hello); | |
| std::cout << "any of int = " << aa.cast<int>() << std::endl; | |
| std::cout << "any of string = " << bb.cast<std::string>() << std::endl; | |
| std::cout << "any of string* = " << *(cc.cast<std::string*>()) << std::endl; | |
| } | |
| // g++ -Wall -std=c++11 simple-any.cpp |