2014-12-29 3 views
0
template<typename FilterComponent, typename ...FilterComponents> 
    std::bitset<components_count> component_impl(std::bitset<components_count> &b){ 
    b.set(FilterComponent::get_id()); 
    return component_impl<FilterComponents...>(b); //ambiguous 
    } 
    template<typename FilterComponent> 
    std::bitset<components_count> component_impl(std::bitset<components_count> &b){ 
    b.set(FilterComponent::get_id()); 
    return b; 
    } 
    template<typename ...FilterComponents> 
    std::bitset<components_count> component_mask(){ 
    std::bitset<components_count> b; 
    component_impl<FilterComponents...>(b); 
    return b; 
    } 

이 함수가 모호한 이유는 무엇입니까? component_impl이 하나 개의 유형 이름으로 호출 될 때 나는 그것이 모호, component_mask<Foo,Bar,Baz>();왜이 가변 함수 호출이 모호한가요?

error: call to member function 'component_impl' is ambiguous 
    return component_impl<FilterComponents...>(b); 
+0

Testcase please ...... 모든 질문에 대해 왜 테스트 케이스를 요청해야합니까? 왜 그 중요성을 이해하기가 어렵습니까? 그리고 왜 아무도 인터넷에 게시하기 전에 그것들을 구성하지 않습니까? 아우 !!! –

+0

@ LightnessRacesinOrbit 좋아, 잠시만 기다려주세요. –

+7

'FilterComponents'가 하나의 요소만을 가지고있을 때, 두 함수 템플릿은 똑같은 템플릿 인자로 인스턴스화 될 수 있습니다. – 0x499602D2

답변

2

처럼 전화를 원했다. 첫 번째 버전은 빈 typename 팩과 일치합니다. 두 번째 버전은 또한 일치합니다.

변형 된 템플릿 버전을 typename 팩 앞에 두 개의 typename이 있도록 변경하십시오. 그러면 두 기능이 모호해질 것입니다. FilterComponents...이 비어 있거나 하나 개의 요소가있는 경우 두 기능 템플릿을 동일하게 실행 가능하기 때문에

template<typename FilterComponent1, typename FilterComponent2, typename ...FilterComponents> 
std::bitset<components_count> component_impl(std::bitset<components_count> &b){ 
    b.set(FilterComponent1::get_id()); 
    return component_impl<FilterComponent2, FilterComponents...>(b); 
} 
5

은 모호성이있다. 첫 번째 템플리트 선언에 두 번째 템플리트 인수를 추가하여 모호성을 해결할 수 있습니다 (예 : R Sahu). 또한 동일한 효과를 얻기 위해 초기화 목록에 인수를 풀 수 :

template<typename... FilterComponents> 
std::bitset<components_count> component_impl(std::bitset<components_count>& b) 
{ 
    using discard = int[]; 
    (void)discard{ 0, (b.set(FilterComponents::get()), void(), 0)... }; 
    return b; 
} 

첫 번째 00를 후행하는 것은 빈 매개 변수 팩을 보상하고 정수 따라서 폐기로 목록을 채우는 것입니다 void() 유형. void()은 반환 값 set()을 "지우"므로 반환 유형에서 과부하 operator,()을 사용할 수 없게됩니다. (우리는 std::bitset::set()을 가지고 있지 않지만 일반적인 경우에는 사용하는 것이 유용합니다).

이렇게하면 재귀를 돕기 위해 두 번째 오버로드가 필요하지 않습니다.

+2

그것은 별도의 도우미 함수에 대한 필요성을 제거합니다. –

+0

좋은 해결책. 그'0'과'void()'에 대한 설명은 어긋나지 않을 것입니다! –

+1

첫 번째 0은 팩 확장 외부로 나가야합니다. –