2014-05-13 4 views
6

링커를 찾기위한 I는 다음과 같이 명시 적으로 내 템플릿을 인스턴스화 할 수 있도록 내가 부분적으로 CPP 파일에 구현 (일부 추상적 인 방법으로) 여러 템플릿 클래스 Impl 있습니다명시 템플릿 인스턴스화

template class Impl<T0>; 
template class Impl<T1>; 
template class Impl<T2>; 
... 
template class Impl<Tx>; 

유형 수가 Tx으로 증가함에 따라 필요한 모든 파일에서 이러한 명시 적 인스턴스화 목록을 수동으로 확장하는 것보다 더 나은 방법을 찾고 싶습니다. 나는이에 대한 가변 인자 템플릿을 사용할 수 있다고 생각, 그래서 나는 다음을 시도 :

template <template <class> class, class...> 
struct type_map; 

template <template <class> class BaseT, class... Ts> 
struct type_map<BaseT, std::tuple<Ts...>> { 
    using type = std::tuple<BaseT<Ts>...>; 
}; 

typedef std::tuple<T0, T1, T2> MyTypes; 

그리고 CPP 파일에

: 내가 의도 한대로

template class type_map<Impl, MyTypes>; 

그러나,이 템플릿을 인스턴스화하지 않았다합니다 (링커가 누락 된 기호에 대해 불평 함).

이 접근 방식을 작동 시키거나 (즉, 템플릿을 인스턴스화하지 않고 템플릿을 인스턴스화하는 방법) 또는이 상황에서 내 문제를 해결할 수있는 전혀 다른 접근 방식이 있습니까?

+0

dll을 만들려고합니까? 어쩌면 당신은 당신의'type_map' 타입에 export 매크로를 추가해야만합니다. –

+1

@Angew 저처럼 작동하는 여러 클래스가 있습니다. 이것이 내 문제의 이유입니다. 제 질문을 조금 더 분명하게하려고했습니다. – fschoenm

+0

@vlad_tepesch 아니요, DLL을 사용하지 않습니다. 이것은 컴파일러가 다른 컴파일 단위에 필요한 템플릿 인스턴스를 생성하지 않는 문제와 관련이 있습니다. – fschoenm

답변

2

나는 variadic 템플릿으로 이것을 할 수 있다고 생각하지 않지만 프리 프로세서로 할 수있다.

두 가지 옵션이 있습니다. 하나는 사용하는 것입니다 Boost.Preprocessor :

// Definitions: 
#define ARGUMENTS (T0)(T1)(T2)(T3)(Tx) 

#define INSTANTIATE(maUnused, maTemplate, maType) \ 
    template class maTemplate<maType>; 


// Usage: 
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl, ARGUMENTS) 

BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl2, ARGUMENTS) 

또 다른 옵션은 X macro 트릭을 사용하는 것입니다 :

x.hpp

X(T0) 
X(T1) 
X(T2) 
X(T3) 
X(Tx) 

#undef X 

using_file.cpp

#define X(maType) template class Impl<maType>; 
#include "x.hpp" 

#define X(maType) template class Impl2<maType>; 
#include "x.hpp" 
+0

불행히도이 경우에는 다른 방법이 없다고 생각합니다. 내 클래스가 추상적이지 않은 경우에만 variadic 템플릿 메서드를 사용할 수 있습니다. 어쨌든 고마워! – fschoenm

관련 문제