標籤:hello base blog name == const clu struct bad
#include <iostream>#include <string>#include <type_traits>#include <utility>#include <stdexcept>#include <typeindex>#include <exception>using namespace std;struct Any{ Any(void) : m_tpIndex(std::type_index(typeid(void))) {} Any(const Any& that) : m_ptr(that.Clone()), m_tpIndex(that.m_tpIndex) {} Any(Any && that) : m_ptr(std::move(that.m_ptr)), m_tpIndex(that.m_tpIndex) {} //建立智能指標時,對於一般的類型,通過std::decay來移除引用和cv符,從而擷取原始類型 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); } template<class U> bool Is() const { return m_tpIndex == std::type_index(typeid(U)); } //將Any轉換為實際的類型 template<class U> U& AnyCast() { if (!Is<U>()) { std::cout << "can not cast " << typeid(U).name() << " to " << m_tpIndex.name() << std::endl; //throw std::logic_error{ "bad cast" }; } else { 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; }private: 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 != nullptr) return m_ptr->Clone(); return nullptr; } BasePtr m_ptr; std::type_index m_tpIndex;};int main(int argc, char *argv[]){ map<string, Any> one; one["one"] = 1; one["two"] = 1.2; one["three"] = "hello"; one["four"] = string("word"); vector<int> two = { 1, 2, 3, 4, 5 }; one["five"] = two; cout << one["one"].AnyCast<int>() << endl; cout << one["two"].AnyCast<double>() << endl; cout << one["three"].AnyCast<const char*>() << endl; cout << one["four"].AnyCast<string>() << endl; vector<int> tmp = one["five"].AnyCast< vector<int> >(); for (auto it = tmp.begin(); it != tmp.end(); ++it) { cout << *it << endl; } getchar(); return 0;}
c++11 Any