2017-12-27 7 views
2

나는 getVector 멤버 함수를 전문으로하고 싶습니다. 이것을 위해 SFINAE를 사용하려고합니다. Dim이 3 이상인 경우에만 작동합니다.SFINAE 템플릿 멤버 오버로드

template <size_t Dim> 
class Mat 
{ 
    ... 
    template <size_t VDim, typename enable_if<(Dim > 1 && VDim == 0)>::type* = nullptr> 
     void getVectorBegin(const array<size_t, Dim - 1>& indexAfter) const; 

    template <size_t VDim, typename enable_if<(Dim > 2 && 0 < VDim && VDim < Dim-1)>::type* = nullptr> 
     void getVectorBegin(const array<size_t, VDim>& indexBefore, const array<size_t, Dim - VDim - 1>& indexAfter) const; 

    template <size_t VDim, typename enable_if<(Dim > 1 && VDim == Dim-1)>::type* = nullptr> 
     void getVectorBegin(const array<size_t, Dim - 1>& indexBefore) const; 
}; 

Mat<3> m; 
Mat<2> m; // error C2039: 'type': is not a member of 'std::enable_if<false,_Ty>' 
+0

"Dim> x"수표를 마지막 && 용어로 사용 해보려고 시도 했습니까?나는 컴파일러가 옳은지 확실하지 않거나 단지 정의 된 구현이지만, enable_if 조건을 shortcircuit하고 VDim에 종속되지 않는 값을 고려할 수 있으므로 멤버 선언 인스턴스 생성 중에 컴파일러 오류가 발생합니다 (Mat <2>). 인스턴스 포인트) –

+0

우리에게 보여주지 않는 것이 있습니다. 템플릿 클래스의 멤버 함수는 사용되지 않으면 인스턴스화되지 않습니다. 전화 사이트를 보여 주시겠습니까? – papagaga

+4

@papagaga가 완전히 올바르지 않은 경우 클래스 템플릿이있을 때 멤버 함수 선언 (정의가 아닌)이 인스턴스화됩니다. 따라서 선언에 클래스 템플릿 매개 변수에 값 전용 * 전용 *이있는 표현식이 포함되어 있고 해당 표현식 결과가 잘못 작성되면 함수가 "사용되지"않은 경우에도 오류가 발생합니다 ... –

답변

2

이것은 까다로울 수 있습니다.

나는 코드가 Dim>=2인데 괜찮다고 생각하지만, Dim<=1 인수가 주어 졌을 때 아무런 진단이 필요 없지만 컴파일러가 불평하는 다른 이유 때문에 잘못 작성되었다고 생각합니다.


Dim>=2을 위해 그것은 정확하지만 컴파일러 (MSVC++ 같아요)는 Dim==2 경우에 뿌려줍니다. 오류 설명을 감안할 때 &식이 enable_if 조건에서 잘못 단락되어 Dim > x이 거짓 일 때 클래스 템플릿 매개 변수에서 값이 인 경우에만으로 해석한다는 이유가 있다고 가정합니다. 해결 방법은 Dim > x 수표를 & & 표현식의 마지막 용어로 이동하는 것입니다.

상황은 다음 코드 조각 개념적으로 유사하다, 정교 : 여기

template <size_t N> 
class foo 
{ 
    template <typename E = enable_if_t<(N>0)>> 
    void bar(); 
}; 

foo<1> f1; 
foo<0> f0; // fails 

, foo의 인스턴스화가는 회원들의 선언의 인스턴스 (그러나 정의) ([참조 트리거 temp.inst] # 1); 구성원에있는에 종속적이라는 이름과 표현식 만 확인하면 템플릿 매개 변수가 각각의 인스턴스화 시점에 연기됩니다. 여기서, 형명 enable_if_t<(N>0)>가 수행 하지bar() 템플릿 파라미터 (Nfoo의 템플릿 매개 변수리스트에 속한다) 따라서 N == 0enable_if<false>::type 결과 비 의존적이므로 오차에 의존한다. 다시 코드 간다


고려 :

[temp.dep.constexpr] 후술하는 바와 같이 임의의 표현식 경우, 상수 값은 식 의존 제외 1 값에 따라 달라짐

예외로 단락 연산자가 언급되지 않았습니다. 따라서 Dim<=1이더라도 표현식, 예를 들어 Dim > 1 && VDim == 0은 값에 따라 달라집니다. 따라서 VDim (SFINAE가 적용될 것임) 대체 시까 지 오류가 발생하지 않아야합니다. 사실, 귀하의 코드를 수락함에있어 gcc와 clang은 모두 agree입니다. 첫 번째와 세 번째 getVectorBegin 과부하 실제로 기능상 동등한 부재 템플릿 선언 Dim<=1 때, 상기

은 ( [temp.over.link] # 6 참조) 그래서이 경우에 잘못 형성된 믿을.