2014-12-08 5 views
0

연구 목적으로 직접 입력합니다. Any. 나는 조건에 따라 Type 또는 Type *을 반환하는 방법을 이해하지 못합니다. 당신이 볼 수 있듯이동일한 함수에서 다른 유형을 반환하는 방법은 무엇입니까?

class any 
{ 
public: 
    template<class T> 
    any(T & d) 
    { 
     data_container = new container_impl<T>(d); 
    } 

    template<class T> 
    any(T* d) 
    { 
     is_pointer = true; 
     data_container = new container_impl<T>(d); 
    } 

    bool check_is_pointer() const; 

    template<class T> 
    T a_cast(size_t id) const 
    { 
     auto real_id = data_container->get_id(); 

     if (real_id != id) 
     { 
      //throw new exeption 
     } 

     return static_cast<container_impl<T>&>(*data_container).get_data(); 
    } 

private: 
    class abstract_container 
    { 
    public: 
     virtual ~abstract_container() { } 
     virtual size_t get_id() const = 0; 
    }; 

    template<typename T> 
    class container_impl : public abstract_container 
    { 
    public: 
     container_impl(T const& value) 
     { 
      data = value; 
      id = type_id<T>(); 
      pointer_data = nullptr; 
     } 

     container_impl(T const* value) 
     { 
      pointer_data = value; 
      id = type_id<T*>(); 
     } 

     T get_data() 
     { 
      return data; 
     } 

     size_t get_id() const override 
     { 
      return id; 
     } 

    private: 
     T data; 
     T const* pointer_data; 

     size_t id; 
    }; 

    abstract_container *data_container = nullptr; 
    bool is_pointer = false; 
}; 

template<class T> 
T any_cast(any const& obj) 
{ 
    size_t id = type_id<T>(); 
    return obj.a_cast<T>(id); 
} 

template<class T> 
T* any_cast(any const& obj) 
{ 
    size_t id = type_id<T>(); 
    return obj.a_cast<T>(id); 
} 

, 나는 다른 형태를 돌려주는 두 가지 기능 any_cast를 만들 싶습니다 :이 클래스의 내 스케치입니다.

+0

는 (아직하지 않은 경우) 부스트를 살펴 :: 어떤이 –

+0

발생한 문제가 무엇입니까? – dlf

+0

@dlf, 오버로드 된 함수 "any_cast"의 인스턴스가 둘 이상 인수 목록과 일치 함 : 함수 템플릿 "T * utils :: any_cast (const utils :: any 및 obj)" 함수 템플릿 "T utils :: any_cast (const utils :: any & obj) "' – Denis

답변

3

다른 유형을 반환 할 수 없습니다. Boost가 실제로하는 방식은 실제로 다른 서명을 사용하는 것입니다. 두 가지 버전이 서로 다른 인수를 사용한다는 점에 유의하십시오. 하나는 참조를 취하고 다른 하나는 포인터를 취합니다. 두 가지 다른 기능의

template <typename T> // this one will try to cast your any down to T 
T any_cast(any&);  // and return it if that succeeds, else throw 

template <typename T> // this one will NOT throw, but will return 
T* any_cast(any*);  // a pointer instead 

사용 예제 :

any a = 5; 
any_cast<double>(a); // throws 

double* v = any_cast<double>(&a); // won't throw 
assert(v == nullptr); 

int* vi = any_cast<int>(&a); // succeeds 
assert(*vi == 5);