2013-03-22 3 views
1

템플릿 클래스가 template<typename T> class TplObject입니다. 인덱스 배열이 typename T 인 정적 구조 종류가 필요합니다. 나는 이런 식으로 할 수있다 :템플릿 클래스의 정적 객체 배열

부스트에 mb 같은 구조가 있는가? 그렇지 않다면 어떻게 만드는지 제안 할 수 있습니까?

+1

* "여기서 색인은'typename T'"입니다. 이것은 의미가 없습니다. 런타임에 "typename T"인스턴스를 만들 예정이라면이 필요성을 필요로 할 수있는 유일한 이유가 있습니다. 어떻게해야할까요? – cdhowie

+0

@cdhowie 오, 음, 예제는 그렇게 좋지 않습니다, 미안 해요. 런타임에이 객체를 추가하고 싶지 않습니다. 나는 컴파일 타임에 빌드되는 객체를 갖고 싶고 다른 템플릿 인자의'TplObject' 클래스의 여러 인스턴스를 가지길 원합니다.이 템플릿 인자는 타입으로 가져올 수 있습니다. – user14416

+0

@ user14416 그런 컨테이너는별로 의미가 없지만 생각하지 않습니다. 찾고있는 것은'std :: map '입니다. 여기서'T'는'std :: type_index' 값에 의존합니다. 데이터 구조에서 포인터를 사용하는 것을 제외하고는 어떻게 구현할 수 있을지 모르겠습니다. 아마 당신은 왜 이것을 필요로하는지 설명 할 수 있으며 대안을 제안 할 수 있습니까? – cdhowie

답변

0

그래서 여기가 예입니다 :이 예는, 각 유형의 하나 개의 객체를 저장할 수

class typemap 
{ 
    std::map<std::type_index, std::shared_ptr<void>> map_; 

public: 
    template<typename T> 
    void set(std::shared_ptr<T> obj) 
    { 
     map_[std::type_index(typeid(T))] = obj; 
    } 

    template<typename T, typename... Args> 
    void emplace(Args&&... args) 
    { 
     this->set(std::make_shared<T>(std::forward<Args>(args)...)); 
    } 

    template<typename T> 
    std::shared_ptr<T> get() 
    { 
     return std::static_pointer_cast<T>(map_[std::type_index(typeid(T))]); 
    } 
}; 

는이 같은 일을 사용하는 이런 식으로하는 것. 템플릿을 인스턴스화하고, 템플릿을 인스턴스화하고, 튜플에 인스턴스를 저장하고, 유형 기반 조회를 제공하는 유형 목록을 취합니다. get 메소드.

#include <type_traits> 
#include <utility> 
#include <tuple> 

// Metaprogramming boilerplate: 
template<typename... Ts> struct type_list {}; 
template<typename T, typename list, typename=void> struct index_in; 
template<typename T, typename T0, typename... Ts> 
struct index_in<T, type_list<T0, Ts...>, typename std::enable_if<std::is_same<T,T0>::value>::type> 
{ 
    enum { value = 0 }; 
}; 
template<typename T, typename T0, typename... Ts> 
struct index_in<T, type_list<T0, Ts...>, typename std::enable_if<!std::is_same<T,T0>::value>::type> 
{ 
    enum { value = index_in<T, type_list<Ts...>>::value+1 }; 
}; 

// The tuple of instantiations of Factory: 
template<template<typename>class Factory, typename... Ts> 
struct PolytypeFactory { 
    std::tuple< Factory<Ts>... > data; 
    template<typename T> 
    Factory<T>& get() { 
    return std::get< index_in< T, type_list<Ts...> >::value >(data ); 
    } 
    template<typename T> 
    Factory<T> const& get() const { 
    return std::get< index_in< T, type_list<Ts...> >::value >(data ); 
    } 
}; 

// a test factory, that creates an instance of T from the constant 100.5: 
template<typename T> struct maker100_5 { T operator()() const { return T(100.5); } }; 

// test code, where I create 100.5 as an int, double and char, then print them: 
#include <iostream> 
int main() { 
    PolytypeFactory<maker100_5, int, double, char> factory; 
    std::cout << factory.get<int>()() << "," << factory.get<double>()() << "," << factory.get<char>()() << "\n"; 
} 

필요한 경우 중 하나 포인터 - 투 - Factory<Ts>를 저장, boost::optional를 사용하는 누군가가 get() 같은 방법을 통해 new 버전에서 통과 할 수 있도록, 또는 정말 멋진 얻어서, PolytypeFactory의 내용의 건설을 연기 할 수 있으며, in-place 건설을하고있다.

0

아마도 std::type_index을 찾고있을 것입니다. std::shared_ptr과 결합하여, 당신을 도울 수있는 다음은 시작하기 :

typemap m; 

// set 
m.set(std::make_shared<int>(42)); 
m.set(std::make_shared<MyClass>()); 
m.set(std::make_shared< std::vector<double> >()); 

// or use emplace 
m.emplace<int>(42); 
m.emplace<MyClass>(); 
m.emplace< std::vector<double> >(); 

// access 
int douglas = *m.get<int>(); 
m.get<MyClass>()->adams(); 
m.get< std::vector<double> >()->push_back(3.141592); 
+0

어떻게 사용하는지 알려주세요. – 0x499602D2

+0

@David : 편집 됨. –

관련 문제