2010-08-16 2 views
5

this question에 답하려고 시도하는 동안 유형이 다형성 이었는지 여부에 따라 메소드 오버로드를 허용하려면 enable_if + disable_if을 사용하고 싶습니다. 아주 순종하는 것enable_if + disable_if 조합을 ​​사용하면 모호한 호출이 발생합니다

template <class T> 
void* address_of(T* p, 
       boost::enable_if< boost::is_polymorphic<T> >* dummy = 0) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
void* address_of(T* p, 
       boost::disable_if< boost::is_polymorphic<T> >* dummy = 0) 
{ return static_cast<void*>(p); } 

struct N { int x; }; 


int main(int argc, char* argv[]) 
{ 
    N n; 
    std::cout << address_of(&n) << std::endl; 
    return 0; 
} 

:

그래서 나는 작은 테스트 파일을 만들었습니다.

그러나 GCC이에 (3.4 ...) 초크 :

test.cpp: In function int main(int, char**) :
test.cpp:29: error: call of overloaded address_of(N*) is ambiguous
test.cpp:17: note: candidates are: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) [with T = N]
test.cpp:20: note: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) [with T = N]

그것은 여기 사용해야 과부하 내 인간의 마음에 오히려 명확한 것 같다. 나는 대안을 정의했고 한 번에 하나의 기능 만 사용할 수 있다는 것이 분명해 보인다. SFINAE가 불필요한 과부하를 무효화 할 것이라고 생각했을 것이다.

disable_if 대신 ... (줄임표)를 사용하여 패치를 적용하고 더미 두 번째 인수가 필요합니다 ...하지만 여전히 컴파일러가이 문제에 대해 궁금한 점이 있습니다. enable_if의 "반환 형식"버전을 사용

답변

11

컴파일러는 숨 막혀. 템플리트는 항상 정의됩니다. 표현식이 true (enable_if 일 경우) 또는 false (disable_if 일 경우) 인 경우에만 회원 type이 존재한다는 것입니다. 후행 ::type없이

template <class T> 
void* address_of(T* p, 
       typename boost::enable_if< boost::is_polymorphic<T> >::type* dummy = 0) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
void* address_of(T* p, 
       typename boost::disable_if< boost::is_polymorphic<T> >::type* dummy = 0) 
{ return static_cast<void*>(p); } 

는 함수 템플릿은 enable_if 또는 두 번째 매개 변수로 disable_if의 인스턴스에 대한 포인터를 가지고 과부하를 만들 수 있습니다. 트레일 링 ::type을 사용하면 템플릿은 void* 유형의 두 번째 매개 변수로 오버로드를 만들거나 과부하가 제거됩니다 (예 : 원하는 동작).

+0

저주를! 나는 그것이 작동해야한다는 것을 알았다. .. –

0

3.4.4에서 작동 : 당신이 enable_ifdisable_if에 후행 ::type를 잊었 때문에 gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

#include <boost/utility/enable_if.hpp> 
#include <boost/type_traits/is_polymorphic.hpp> 
#include <iostream> 

template <class T> 
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type 
address_of(T* p) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type 
address_of(T* p) 
{ return static_cast<void*>(p); } 

struct N { int x; }; 


int main(int argc, char* argv[]) 
{ 
    N n; 
    std::cout << address_of(&n) << std::endl; 
    return 0; 
}