2013-01-14 1 views
2

다음 코드 '표준 : is_constructible <을 >을 int로'g을 사용하여대체 오류가 때때로 오류입니까? 구현하려고 snipplet

#include <type_traits> 

struct A { 
    // A(int); 
}; 

template< typename T > 
struct cstr_int 
{ 
    static int mi; 

    template< typename C > 
    static typename std::enable_if< 
    std::is_same< decltype(T(mi)), T >::value, char >::type choose(C *); 
    static long choose(...); 

    enum { value = (sizeof(decltype(choose(& mi))) == 1) }; 
}; 

bool const b1 = cstr_int<A>::value; 

++이 잘 작동; 다음과 같은 오류가 인쇄 ++ 연타를한다 사용 :

tmp/sfinae04.cc:14:29: error: no matching conversion for functional-style cast from 'int' to 'A' 
    std::is_same< decltype(T(mi)), T >::value, char >::type choose(C *); 
          ^~~~~ 
tmp/sfinae04.cc:20:17: note: in instantiation of template class 'cstr_int<A>' requested here 
bool const b1 = cstr_int<A>::value; 
       ^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument 
struct A { 
    ^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument 
struct A { 
    ^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided 
1 error generated. 

버전 정보 : 그 소리 버전 3.3 (트렁크 172418) (LLVM/트렁크 172417), g ++ (데비안 4.7.2-4) 4.7.2.

내 질문 : IMHO 이것은 SFINAE 여야합니다. 내가 여기에 뭔가를 놓치거나 clang ++에 문제가 있습니까?

은 (내가 is_constructible 있다는 것을 알고있다()하지만 난 그것을 사용할 수 아니에요 - 그리고 내 질문의 요점이 아닙니다.)

+2

나는 문제가 당신이'enable_if'에 T가 아니라 C를 사용하는 것이 믿습니다. T = A가 이미 알려져 있기 때문에 대체 실패가 없습니다. –

+0

예 - 당신 말이 맞습니다 : 이것은 Bart van Ingen Schenau가 대답 한 것과 정확히 일치합니다. 감사. –

답변

6

가 당신에게 교체의 실패처럼 보일 수 있지만, 실제로는 템플릿 인스턴스화 중에 감지 된 오류이므로 진단 가능한 오류입니다.

enable_if은 추론중인 템플릿 매개 변수에 의존하지 않으므로 SF0AE 컨텍스트는 이 아니며이 아닙니다.

이 작동합니다

template< typename T > 
struct cstr_int 
{ 
    static int mi; 

    template< typename C > 
    static typename std::enable_if< 
    std::is_same< decltype(C(mi)), C >::value, char >::type choose(C *); 
    static long choose(...); 

    enum { value = (sizeof(decltype(choose((T*)0))) == 1) }; 
}; 
+0

Uups! 당신의 힌트를 주셔서 대단히 감사합니다 - 나는 눈이 멀었 음에 틀림 없다 ... –