이 문제는 설명하기가 좀 어렵다, 그래서 예를 들어 시작할 것이다 : 나는 유형과 템플릿 매개 변수로 정수 상수를 취하는 클래스 템플릿을템플릿 전문화
하고, 나는 그 템플릿의 인스턴스화에서 파생 자식 클래스의 수 있습니다
template <class V, int i>
struct Base
{
static void doSomething() { cout << "something " << i << endl; };
};
struct Child : public Base<int,12>
{
};
내가 다른 템플릿으로 이러한 클래스를 사용하려면 서로 다른 종류의 전문이있는, (의 테스트를 부르 자). Base의 인스턴스화에서 파생 된 모든 클래스에 대해 동작이 동일해야하므로 Base에서 파생 된 모든 클래스를 처리하는 Test의 단일 전문화 만 정의하려고합니다.
Base < V, i >에 직접 적용 할 수 없다는 것을 알고 있습니다. 하위 클래스를 감지하지 못하기 때문입니다. 대신, 내 첫 번째 방법은 부스트의 enable_if 및 유형 특성을 사용했다 :
// empty body to trigger compiler error for unsupported types
template <class T, class Enabled = void>
struct Test { };
// specialization for ints,
// in my actual code, I have many more specializations here
template <class Enabled>
struct Test <int, Enabled>
{
static void test (int dst)
{
cout << "Test<int>::test(" << dst << ")" << endl;
}
};
// this should handle all subclasses of Base,
// but it doesn't compile
template <class T, class V, int i>
struct Test <T, typename enable_if <is_base_and_derived <Base <V,i>, T>>::type>
{
static void test (const T &dst)
{
dst.doSomething();
}
};
int main (int argc, char **argv)
{
Test <int>::test (23);
Test <Child>::test (Child());
return 0;
}
아이디어는 전문화가 V와 I의 임의의 값으로 자료에서 파생 된 모든 클래스를 처리해야했다. 이 작동하지 않습니다, GCC는 불평 :
error: template parameters not used in partial specialization: error: ‘V’ error: ‘i’
나는 문제가이 방법은 V의 모든 가능한 조합을 시도하는 컴파일러를 필요로하고 그 중 하나가 일치하면 내가 확인하는 것입니다 같아요.
template <class V, int i>
struct Base
{
typedef V VV;
static constexpr int ii = i;
static void doSomething() { cout << "something " << i << endl; };
};
이 방법은, 전문화가 더 이상 V가 있어야하고 난 무료 템플릿 매개 변수 :
template <class T>
struct Test <T, typename enable_if <is_base_and_derived <Base <typename T::VV, T::ii>, T>>::type>
{
static void test (const T &dst)
{
dst.doSomething();
}
};
그리고 지금, 나는 기본 클래스에 뭔가를 추가하여 문제를 해결했다 그것은 컴파일됩니다.
자, 내 질문은 : 어떻게하면 기본 클래스를 수정하지 않고도이 작업을 수행 할 수 있습니까?이 경우 직접 작성했기 때문에 가능했지만 테스트 템플릿에서 제 3 자 라이브러리 코드를 처리해야한다면 어떻게해야합니까? 보다 우아한 솔루션이 있습니까?
편집 : 또한 누군가가 나에게 왜 정확하게 첫 번째 접근 방식이 작동하지 않는지에 대한 자세한 설명을 줄 수 있습니까? 나는 대략적인 생각을 가지고 있지만 적절한 이해를 원합니다. :-)
간단한 해결책이Base
을 수 있도록하는 것입니다
Base_Base 팁을 주셔서 감사합니다. 현재 코드를 좀 더 읽기 쉽게 만들어줍니다. 그러나 제 3 자 라이브러리의 경우 하위 클래스가 라이브러리에도 속해있는 경우에는 작동하지 않습니다. –
@BenjaminSchug : 아마도 [this] (http://stackoverflow.com/a/6398983/1324131)는 편집 된 질문에서 새 질문에 대한 답변을 제공합니다. – user2k5
감사합니다. 첫 번째 방법이 효과가 없었던 이유입니다.내 직감이 맞는 것처럼 보입니다. –