2012-12-05 9 views
7

템플릿 별칭 (, 예 : 누락 된 멤버 typename의 템플릿 별칭, 아래 코드 조각과 같이)이 포함 된 대체 오류의 경우 오류가 발생해야합니까? 올바른 누가, 왜 : 그래서 질문은템플릿 별칭 및 파일

// some types 
struct bar { }; 

struct foo { 
    typedef void member_type; 
}; 


// template alias 
template<class T> 
using member = typename T::member_type; 


template<class T> 
void baz(...) { } 

// only works for gcc, clang fails with: no type named 'member_type' 
// in 'bar' 
template<class T> 
void baz(member<T>*) { } 


int main(int, char**) { 

    baz<bar>(0);   // picks first 
    baz<foo>(0);   // picks second 

    return 0; 
} 

을 :

연타와 GCC는 이것에 동의하는 것? 기준에 따르면

+0

'clang -v'는 무엇을 말합니까? Clang 3.3 트렁크는 코드를 잘 컴파일합니다. – Xeo

+0

여기 데비안 clang 버전 3.1-8은 기다릴 필요가 있습니다. 귀하의 의견에 감사드립니다! – max

+0

조금 단순화하기 위해 템플릿 별칭을 제거 할 수 있습니까? – David

답변

4

:-)

감사합니다, 그것은 별칭 템플릿을 즉시 교체해야하고 보통/보통 SFINAE 나중에 T이 알고있을 때 typename T::member_type에 적용되기 때문에, 정확하다는 것을 분명히 GCC입니다.

그러나 현재이 문제가 있습니다 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554 참조).

회의 결과에 따르면 clangs 동작이 필요합니다. T의 대체는 별칭 템플릿의 컨텍스트에서 수행됩니다 (typename T::member_type의 대체 시간에 별칭에 대한 참조가 없더라도 템플릿이 더 이상 필요하지 않습니다. 매개 변수 유형 패턴의 출처로 참조되어야합니다.


이 표준은 규범 적 매개 변수 인 것은 분명하다 내 의견으로는, 너무이 경우 인스턴스화 의미를

template<int I> 
void f(int x[I]); 

int main() { 
    f<0>(nullptr); 
} 

에 영향을 줄 수있는 패턴을 정의 시간에 멀리 던져 다른 상황과 유사 즉시 int*으로 대체되므로 인스턴스화가 작동합니다. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322을 참조하십시오.

+5

"회의 결과에 따르면, clangs 동작이 필요합니다"- 이것이 EnableIf라는 별칭을 완전히 없앨 수는 없을까요? 별칭 템플릿을 사용하여 SFINAE 소프트 오류를 ​​생성하지 않는 것이 바람직합니다. – Xeo

+0

@Xeo 네, 그렇게 나쁠 것입니다. 실제로 clang 트렁크는 EnableIf 별칭을 허용하기 때문에 Asker가 관찰 한 동작이 단순한 버그였으며 wg21 사이트의 문제 요약은 혼란 스럽습니다 (IMHO). –

+0

그래, 나는 트렁크가 코드를 잘 컴파일했다고 이미 논평 한 이후로 혼란스러워했다. – Xeo