2015-01-11 6 views
0

모든 데이터 유형의 멤버를 갖는 이벤트 클래스를 만들고 비 템플릿 클래스로 만들고 싶습니다. 하지만 템플릿 형식의 콘텐츠를 제공하는 콘텐츠를 설정할 수 있습니다. 이벤트 클래스의 내용을 사용하는 핸들러 함수가 있습니다.비 템플릿 클래스의 중첩 템플릿 멤버를 반환하십시오.

NewEvent.h 파일

class NewEvent { 
public: 
    NewEvent(const int64_t& value = 0) : value_(value) {} 

    int64_t value() const { return value_; } 
    void set_value(const int64_t& value) { value_ = value; } 

    class ElementBase { 
    public: 
    virtual ~ElementBase() {} 
    template <typename ContentT> ContentT& content() const; 
    template <typename ContentT> void set_content(const ContentT&); 
    }; 

    template <typename ContentT, typename Allocator = std::allocator<ContentT>> 
    class Element : public ElementBase { 
    public: 
    Element(const Allocator& alloc = Allocator()) : alloc_(alloc) {} 

    typedef std::allocator_traits<Allocator> AllocatorTraits; 

    ContentT& content() const { 
     return content_; 
    } 
    void set_content(const ContentT& content) { 
     AllocatorTraits::construct(alloc_, &content_, content); 
    } 

    protected: 
    ContentT content_; 
    Allocator alloc_; 
    }; 

    template <typename ContentT> 
    void set_content(ContentT& content) { 
    ElementBase* element = new Element<ContentT>(); 
    element->set_content(content); 
    content_.reset(element); 
    } 

    template <typename ContentT> 
    ContentT& content() const { 
    return content_->content<ContentT>(); 
    } 

private: 
    int64_t value_; 

    std::unique_ptr<ElementBase> content_; 
}; 

template <typename ContentT> 
ContentT& NewEvent::ElementBase::content() const { 
    return dynamic_cast<NewEvent::Element<ContentT>&>(*this).content(); 
} 

template <typename ContentT> 
void NewEvent::ElementBase::set_content(const ContentT& content) { 
    dynamic_cast<NewEvent::Element<ContentT>&>(*this).set_content(content); 
} 

하여 Main.cpp 내 코드에서

struct Data { 
    int returns; 
}; 
void print(Data data) { 
} 
int main() { 
    struct Data data; 
    // ... 
    NewEvent new_event; 
    new_event.set_content<Data>(data); 

    print(new_event.content()); 
    return 0; 
} 

는 set_content 기능이 제대로 작동합니다. 하지만 content()를 수신하고 콘텐츠 유형에 따라 호출하는 방법을 모르겠습니다. NewEvent 클래스의 content() 함수에 컴파일 오류가 있습니다.

오류 C2783 : 'ContentT & NewEvent :: ElementBase :: 컨텐츠 (무효) CONST은'에 대한 템플릿 인수를 추론 할 수없는 'ContentT'이 추론 유형의 문제를 해결하거나 거기는 다른 방법입니다 방법

이런 식으로 구현합니까? 함수에서

답변

0

: 여기

template <typename ContentT> 
ContentT& content() const { .. } 

ContentT 수 없습니다 추론 - 컴파일러가 따라서 (전화 content()의 버전 오류를 판별하는 데 사용할 수를 호출 할 때 당신은 아무것도 제공하지 않는). content<Date>() 또는 content<int>() 중 어느 것을 원하는지 여부를 어떻게 알 수 있습니까? 당신은 명시 적으로 set_content()라고 할 때했던 것과 같은 방법으로 호출 사이트의 유형을 제공해야합니다 :

print(new_event.content<Date>()); // now compiler knows which content() to call. 

(경우에 사용하려는, 당신이 구현하는 것이 효율적 boost::any과 동일합니다 해당 유형 대신.