2013-03-08 3 views
4

나는 C++ 템플릿 수수께끼를 발견했습니다. 나는 그것을 최소한으로 줄이려고 노력했다. 그리고 지금 내가하려고하는 것이 가능하다해도 나는 확신 할 수 없다. 다음 코드를 살펴보십시오 (일부 .h 파일에서).템플릿 Conundrum

//This one works: 
A<B1> first; 
first.f<int>(5); 

//This one does not work: 
A<B2<int>> second; 
second.f<int>(5); 

나는 때문에 두 번째 부분의 얻을 오류 메시지가

error C3860: template argument list following class 
      template name must list parameters in the 
      order used in template parameter list 

error C3855: 'A<T>': template parameter 'T' is 
      incompatible with the declaration 

문제가 어떤 생각입니다 : 내 main 기능에

template<typename T> 
class A 
{ 
public: 
    template<typename S> 
    void f(S x); 
}; 

class B1 { }; 

template<typename S> 
class B2 { }; 

//This one works: 
template<> 
template<typename S> 
void A<B1>::f(S x) 
{ 
}  

//This one does not work: 
template<> 
template<typename S> 
void A<B2<S>>::f(S x) 
{ 
} 

나는 이런 일이?


편집

여기 내 동기 부여의 문제가보다 구체적인 확인하십시오. 위의 함수 fT=std::tuple<T1, T2>, T=std::tuple<T1, T2, T3>T=std::tuple<T1, T2, T3, T4>에 대해 특수화되어 있고 tuple의 유형은 아직 언 바인딩되어 있어야합니다. 템플릿에 다른 템플릿을 전달하려는 경우

+1

무엇을하려고합니까? 아마 더 좋은 방법이있을 것입니다. – Pubby

+0

이것이 원하는 것입니까? http://stacked-crooked.com/view?id=8b9365eab6441615b312ad76b0500bb7-18aa934a8d82d638dde2147aa94cac94 – Pubby

+0

@Pubby 동기 부여가있는 섹션을 마지막에 추가했습니다. –

답변

4

멤버 함수 템플릿을 부분적으로 특수화하려고합니다. 그건 불가능합니다, 나는 두려워요 ...

1

, 당신은 template template parameters를 사용하는, 그래서를 A <> 템플릿은 다음과 같을 것이다 :

template<typename T> 
class A 
{ 
public: 
    template<template <typename> class H, typename S> 
    void f(H<S> x); 
}; 

지금 당신은 당신의 템플릿에 템플릿을 전달할 수 있습니다.

원본 템플릿이 이러한 매개 변수 유형을 사용하지 않은 경우 템플릿 템플릿 매개 변수를 전문적으로 설정할 수 있다고 생각하지 않습니다.

+2

이 경우에는 그렇게 생각하지 않습니다. 그는'int'도 일하기를 원한다. – Pubby

+0

나는 지금 이것을보고있다 ... 그것이 나를 위해 일하는지에 관해 당신에게 앙갚음을 할 것이다. 유망 해 보인다. –

3

코드에 두 가지 문제점이 있습니다.

second.f<B2<int>>(5); 

SB2<int>을로 설정 : 나는 그것이 작동하고 이제 두 번째 문제가 노출

template<> 
template<typename S> 
void A<B2<int>>::f(S x) 
{ 
} 

에 있음을 변경하는 경우

template<> // parameters useable for the specialization of A you refer to 
      // since it is a function, no partial specialization is allowed. 
template<typename S> // parameters for the function's parameters 
void A<B2<S>>   // S can not be used here! 
      ::f(S x) // only here 
{ 
} 

때문에 첫째, 둘째 전문화, 불법 함수는 매개 변수 S x을 필요로합니다. 그러나 5 정수는 해당 유형으로 변환 할 수 없습니다. 변경 :

B2<int> x; 
second.f<B2<int>>(x); 

그리고 잘 작동합니다.

해결할 수없는 문제가 해결되지 않을 수도 있으며, 어떤 일이 발생하는지 설명합니다.


당신의 편집에 대한 생각 : 나는 당신이 T=std::tuple<...>에 대한 전문하려고한다는 사실은 이미 방향을 가리키는 생각 : T는 당신이 전문해야하는지이라는 템플릿 A의 매개 변수와 입니다.아마도 다음과 같을 수 있습니다 :

template< typename T > 
class F // used to implement f(), so you can specialize 
     // just F/f() instead of the whole class A 
{ 
    void f(T x) { /* default impl */ } 
}; 

template< typename T1, typename T2 > 
class F< std::tuple< T1, T2 > > 
{ 
    void f(T1 x, T2 y) { /* special impl */ } 
}; 

template< typename T > 
class A : public F<T> 
{ 
    // ...other stuff... 
};