汎用vector(穴を掘ってから記入します).

3008 ワード

 #include <iostream>
#include <type_traits>
#include <vector>
#include <functional>
#include <typeinfo>
class Any{
 public:
  template<typename U>
  using StorageType = typename std::decay<U>::value;
  
  // std::endabled_if< !std::is_same<StrageType<Z>, Any<Z>>::value, void>::type > , Z . 
  
  template<typename Z, class = typename std::enable_if<!std::is_same<StorageType<Z>, Any>::value, void>::type>
  Any(Z&& m_value):ptr(new Container<StorageType<Z>>(std::forward<Z>(m_value)))
  {
   std::cout<<"constructor"<<std::endl;
  }
  
  Any():ptr(nullptr){}// . 
  
  
  ~Any()//  
  {
   if(ptr != nullptr){
    delete ptr;
   }
  }
  
  Any(const Any& copy):ptr(copy.ptr)//  
  {
   std::cout<<"copy for constructor"<<std::endl;
  }
  
  Any(Any&& m):ptr(m.ptr)// . 
  {
   if(m.ptr != nullptr){
    m.ptr=nullptr;
   }
  }
  
  template<typename L>
  inline operator L()const
  {
   return this->as<StorageType<L>>();
  }
  
  template<typename tt>
  inline StorageType<tt> as()
  {
   typedef StorageType<tt> tempType;
   
   if(ptr == nullptr){
    std::cout<<"there is nothing!"<<std::endl;
    throw std::bad_cast();
    
   }else{
    auto tempPtr=dynamic_cast<Container<tempType>*>(ptr);
    
    if(tempPtr == nullptr){
     throw std::bad_cast();
    }
    
    return tempPtr->value;
   }
  }
  
  template<typename TT>
  inline StorageType<TT> valueFunc() // inline class inline . 
  {
   return this->as<StorageType<TT>>();
  }
  
  
  private:
   
   // pure-virtual-class Any . 
   class ContainerBase{
    public:
    virtual ~ContainerBase(){}
    
    virtual ContainerBase* clone()const=0;
   };
   
   
   template<typename X>
   class Container:public ContainerBase{
    public:
     
     template<typename Y>
     Container(Y&& _value):value(std::forward<Y>(_value)){}
     
     ~Container(){}
     
     virtual Container* clone()const override
     {
      return new Container<X>(this->value);
     }
     
     X value;
   };
   
   ContainerBase* ptr;
};
Any::ContainerBase*  Any::ContainerBase::clone()const
{
 return nullptr;
}
struct PollyTypePush{
 
 template<typename Ty>
 void operator()(std::vector<Any>& container, Ty&& value)
 {
  container.emplace_back(std::forward<Ty>(value));
 }
 
};
int main()
{
 short int i=5;
 std::string sTr("shihuawoaini");
 
 std::vector<Any> myContainer;
 auto PollyTypePushFunc=bind(PollyTypePush(), std::ref(myContainer), std::placeholders::_1);
 
 PollyTypePushFunc(1);
 
 std::cout<< myContainer[0].valueFunc<int>() <<std::endl;
 return 0;
}