2016-07-13 3 views
0

클래스의 특정 템플릿 인스턴스화에 대해서만 멤버 함수를 선언 할 수 있습니까?클래스의 특정 템플릿 인스턴스화에만 멤버 함수 선언

// Polynomial<N> is a polynomial of degree N 
template<int N> 
class Polynomial { 
public: 
    //... various shared methods e.g... 
    double eval(double x) const; 
    Polynomial<N-1> derivative() const; 
    Polynomial<N+1> integralFrom(double x0) const; 
    // ... various shared operators etc. 

    double zero() const; // only want Polynomial<1> to support this 
    // only want Polynomial<2> and Polynomial<1> to support the following 
    //  because the solutions rapidly become too difficult to implement 
    std::vector<double> zeros() const; 
    std::vector<double> stationaryPoints() const { return derivative().zeros();} 

private: 
    std::array<double,2> coeffs; 
} 

나의 현재 해결 방법은 단지 N>2에 대한 Polynomial<N>::zeros()에서 예외가 발생하는 것입니다하지만 컴파일시 문제를 감지 좋았을 것이다 : 나는 그것을하고 싶은 이유입니다.

+0

템플릿 전문화가 가능합니까? – Pumkko

+0

C++ 11이 사용 가능하다면'throw' 대신'static_assert (N <= 2, "잘못된 템플릿 인수.")를 사용할 수 있습니다. 컴파일시 바람직하지 않은 기능을 방지합니다. – ilotXXI

+0

어쨌든 전문화가 필요합니다 ('Polynomial '로 인해) –

답변

0

당신은 파생 된 하나에 대해 알고있는 기본 클래스에 zeroszero을 구현하는 CRTP를 사용할 수 있습니다.

그런 다음 조건부로 zeros 및/또는 zero 인 조건부에서 파생되는지 여부.

template<class P> 
struct zeros { /* todo */ }; 

template<class P> 
struct zero:zeros<P> { /* todo */ }; 

struct nozero {}; 

template<int N> 
struxt Polynomial: 
    std::conditional_t< 
    (N==1), 
    zero<Polynomial<N>>, 
    std::conditional_t< 
     (N==2), 
     zeros<Polynomial<N>>, 
     nozero 
    > 
    > 
{ 
    // body 
}; 
0

솔루션은 템플릿 전문화입니다.이 경우 전체 전문화입니다.

그러나 디자인에 대해 생각할 필요가 있다고 생각합니다. 일반적으로 추상화를 이용하지 않기 때문에 다른 케이스에 대해 서로 다른 인터페이스를 정의하는 것은 좋지 않습니다.

예를 들어 stationaPoints() 함수에 대해 생각해보십시오. 이 함수는 제로() 함수가없는 다항식 < 1>이기 때문에이 함수는 다항식 < 2>에 사용할 수 없습니다. 당신의 해답은 인터페이스를 균질화하기 위해 제로 함수를 다항식 <에 추가하는 것입니다.

귀하의 경우, 제로와 제로 (i) 함수가있는 다항식 유형 안에 N-1c 벡터가 들어있는 솔루션을 원합니다. 이 다음이 먼저 계산 계산 된 알고 부울을 추가? 생성자 : 이런 식으로 뭔가 :

template <int N> 
class Polynomial { 
    double _coefs[N+1]; 
    double _zeros[N]; 
public: 
    double zero(size_t i) const { assert(i<N); return _zeros[i]; } 
    // ... 
}; 

이 경우, 당신은 응용 프로그램에 따라, 제로 드 계산하는 전략을 결정할 수 0으로 전화 ...

당신이 coeficients를 저장하는 c- 벡터를 선호한다면이 솔루션은 더 재미있을 것 같아요, 당신은 제로() 함수의 벡터 기반 인터페이스를 좋아하지 않을 것입니다. , 그랬니?

+0

'Polynomial '제 질문에 N 차수의 다항식입니다. N + 1 개의 계수를가집니다. 답을 수정 하시겠습니까? – Museful

+0

또한 더 나은 디자인을 제안 할 수 있습니까?내 현재 솔루션은 계수 배열을 저장합니다. 나는 그것을 보여주기 위해 질문을 편집 할 것이다. – Museful

0

std::enable_if을 SFINAE에 사용하여 제로 기능을 사용할 수도 있습니다.

template< int I > 
class Poly { 

public: 
    template<int Ib = I, typename = std::enable_if_t<Ib == 1> > 
    double zero() 
    { 
     return 42; 
    } 
}; 

int main() 
{ 
    Poly<10> does_not_compile; 
    does_not_compile.zero(); 

    //Poly<1> compile; 
    //compile.zero(); 
} 
+0

이것은 기술적으로 잘못된 프로그램이며 진단 필요하지 않습니다. – Yakk

+0

왜? 어떤 규칙을 어기는거야? – Pumkko

+0

내 대답이 업데이트되었습니다. 위의 것이 더 좋습니까? – Pumkko

관련 문제