SFINAE 잘못된 기능이 유형이나 배열 형 parameters?
문제
이점을 고려하여 문의하시기 바랍 코드:
template<typename T>
char (&f(T[1]))[1];
template<typename T>
char (&f(...))[2];
int main() { char c[sizeof(f<void()>(0)) == 2]; }
이메일 주소와 비밀번호 하 SFINAE 및 선택 두 번째로 과부하므로,대체 T
로 T[1]
금
void [1]()
는 잘못된 형식의 코스입니다.의 조정 매개변수 유형(배열->포인터)은 대체한 후 템플릿을 매개로 기능 매개 변수 및 확인에 대한 유효한 결과 유형을 다음과 같 14.8.2[temp.공제]설명합니다.
하지만 모두 꼬모하고 GCC 컴파일할 수 없습니다.모두 다양 진단을 수행합니다.
객 말한다:
"ComeauTest.c",line2:오류:배열의 기능은 허용되지 않습
char (&f(T[1]))[1];
GCC 말한다(버전 4.3.3
):
오류:ISO C++금지하 제로 크기 배열
c
미,GCC 하지 않는 실패를 대체하지만,그것은 선택의 첫 번째 오버로드 f
, 를 반환 sizeof
1,실패하는 대신하는 대신 그것은 앞까지 같은 꼬모.
무엇을 컴파일러 오른쪽 내 코드는 유효한가?를 참조하십시오거나 견적을 적절한 표준 단면도에서 당신의 대답이다.감사합니다!
업데이트:표준 자체가 포함되어 이러한 예를 목록에서 14.8.2/2
.나도 몰라 왜 그것을 간과 첫:
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array
면 예를 들어 정보만을 보여줍의 의도를 모든 사람들이 절을 보여 위의 코드 작동해야하고 거부하는 첫 번째 과부하 있습니다.
해결책
작은 주이지만,매우 드문,내가 찾은 어떤 경우는 곳에 나가 믿는 꼬모 컴파일러는 그것이 잘못이지만,이러한 경우에는 그래서는 그는 항상 더블 트리플 검사 당신의 가정을!
내가 있는 이유에 대한의 행동은 g++.나는 확실하지 않 그 지정된 정확하게 때 매개변수 유형은 조정:
다음 사항을 고려하십시오:
template<typename T>
struct A
{
void bar (T[10]);
};
template<typename T>
void A<T>::bar (T*)
{
}
의 정의는'바'은 법적으로"T[10]"붕괴를"T*".나 아무것도 표시되지 않은 표준을 금지하는 컴파일러에서 을 수행하의 조정을 8.3.5 에 대하여 템플릿을 선언 고 그것도 성능을 향상에 올 때 하중 초과 일치합니다.
이 적용의 예,g++수 있습 치료로 그것:
template<typename T>
char (&f( T* ))[1];
template<typename T>
char (&f(...))[2];
int main() { char c[sizeof(f<void()>(0)) == 2]; }
위,대체 매개변수의 법적 포인터 기능보다는 배열의 기능이 있다.
그래서 나는 뭔가가있는 경우 prohibts 조정 기능에 대한 매개변수(8.3.5)두 번?
개인적으로,나는 생각을 허용하는 조정생 두 번 이후는 그렇지 않으면 복잡하게 일치하는 기능의 템플릿 오버로드
결론적으로,나는 그것에 대해 유효 g++선택하려면 첫 번째 과부하 기반 방법에 treates 부패 배열을 매개변수,그리고 객 잘못된 것입 지 않습을 공제 실패에 대한 배열의 기능이 있다.
물론 이제는 것을 의미(면 꼬모가 수정되었)다음 각 컴파일러 선택하는 것 다른 과부하고 여전히 수준 을 준수!:(
편집:
다만 나의 점을 설명하기 위하여,다음과 같은 코드를 살펴봅니다:
template <typename T> void foo ( T * );
template <typename T> void foo ( T * const );
template <typename T> void foo ( T [] );
template <typename T> void foo ( T [10] );
template <typename T> void foo ( T [100] );
void bar ()
{
foo < void() > ( 0 );
}
여기에,foo 선언되었다고 다시 선언한다.는 선언하고 그래서는 매개변수 유형,한 컴파일러를 적용 규칙에 나열된 14.8.2?
내 포인트는 표준에 대해 아무것도 말하지 않는다.또한 것으로까지 나아가 말하는 표현이 떠나야하는 것 그것은 하나로 정의되지 않은""또는"정의된 구현"behaviour.
다른 팁
놀랍게도 - 이것은 VS2008에서 작동합니다. 나는 그것이 올바른 행동이거나 그렇지 않다는 증거라고 생각하지 않습니다 ...
Visual Studio는 해석 중입니다
char (&f(T[1]))[1];
t의 크기 1 배열을 가져오고 크기 1의 숯 배열에 대한 참조를 반환하는 함수로서.
표준을 읽는 것으로 이해할 때 템플릿 인수 공제 과정을 설명하려고 노력할 것입니다.
- 명시 적 템플릿 인수는 14.8.2/2에 설명 된대로 확인됩니다.
- 결과 함수 시그니처는 8.3.5에 따라 조정됩니다 (즉, 포인터 붕괴로의 배열이 수행됨).
- 암시 적 템플릿 인수는 14.8.2.1에 따라 추론됩니다 (이것은 2 단계에서 부분적으로 대체 된 서명에서 수행됩니다).
첫 번째 오버로드에 대한 공제는 1 단계에서 실패하므로 과부하 해상도는 두 번째 오버로드를 반환합니다. 나는 프로그램이 잘못되었다고 생각하지 않습니다.