2

C++ Template Metaprogramming을 통해 읽었으며 그 안에 포함 된 연습 문제를 해결했습니다. 문제의 핵심은이 작은 예제에서 볼 수 있습니다.C++ 휴식 템플릿 전문화 모호성

template <class A, class B> 
    struct C; 

    template <class A> 
    struct C<A,A> 
    { 
     typedef some_type type; 
    }; 

    template <class A, class B> 
    struct C<A*,B> 
    { 
     typedef some_other_type type; 
    }; 

    int main() 
    { 
     C<int*,int*> c; 
    } 

c 유형이 모호하기 때문에 컴파일에 실패합니다. 컴파일러는 인스턴스화해야하는 전문 분야를 알 수 없습니다. 그러나 이와 같은 경우에는 첫 번째 전문화를 호출해야합니다. 내가 지금까지 함께 왔어요 솔루션은처럼 다시 작성하는 것입니다이

template <class A, class B> 
    struct C; 

    template <class A, class B> 
    struct C<A*,B> 
    { 
     typedef typename boost::mpl::if_c<boost::is_same<A*,B>::value, 
             some_type, some_other_type>::type type; 
    }; 

이 솔루션의 문제는 실제로 포인터, const를 참조와 배열 유형의 각 부분 전문화, 그래서 내가 '이다 이 수표를 각 전문 분야에 개별적으로 추가해야했습니다.

내 질문은, 다음, 이전의 좋은 소형 전문을 가지고 어떻게 든 컴파일러의 경우 전문화를 대신 다른 전문의의

 template <class A> 
    struct C<A,A> 
    { 
     typedef some_type type; 
    }; 

를 인스턴스화 있도록 조정할 수있는 몇 가지 방법이있다 모호? 관심이있는 사람들을 위해

내가 일하고 있어요 문제는 제 2 장 질문 1

+0

가장 먼저 떠오르는 것은 SFINAE를 사용하여 두 인수가 모두 같을 때 원하지 않는 특수화를 사용하지 않도록 설정하는 것입니다. –

답변

2

당신은 당신의 기본 템플릿에 다른 매개 변수를 추가하고 전문화를 활성화/비활성화하는 데 사용할 수 있습니다. 당신이 가리키는 const 포인터 또는 다른 어떤 일을 처리하려면 지금

template< class A, class B, class Enable = void > 
struct C; 
template< class A > 
struct C<A, A, void> {...}; 
template< class A, class B > 
struct C<A*, B, typename boost::disable_if<boost::is_same<A*, B> >::type> {...}; 

을 당신이 당신의 조건 (... is_const, is_pointer) 특성을 종류에 따라 연장 할 수있다 : 예를 들어, 당신은 할 수 있습니다!

+0

당신의 아이디어를 생각해 보았을 때, 대신에'template :: value> 클래스 C;'를 만들었습니다. 그런 다음 모든 전문 분야에 대해 전문화 템플릿 ' class C {};'을 제외한 세 번째 매개 변수에 대해 'false'를 지정했습니다. 이것은 효과가있는 것으로 보이며 코드가 적습니다. 내가 알아야 할 방법들 사이에 큰 차이점이 있습니까? – SirGuy

+0

코드 작업을 완전히 축하하지만 덜 일반적이며 기본 클래스에서만 예상대로 작동합니다! 템플릿 전문 분야의 변화가 예상되는 경우이 기술을 대신 사용하십시오! – BigBoss

+0

실제로 disable_if 및 enable_if 작동 방법을 읽은 후에 이제는 그 차이점을 이해합니다. 'boost :: disable_if :: type'은 전혀 존재하지 않기 때문에 전문화가 인스턴스화되지 않는 이유입니다. 이 경우 더 구체적인 해결책을 고수 하겠지만 올바른 것으로 표시하겠습니다. – SirGuy