2014-12-06 2 views
1

직교 나 극지로 처리 할 벡터 (연산) 구조를 만들고 싶습니다. 구조는 하나만 있어야하지만 자동으로 적절한 함수로 전달됩니다. 형식 매개 변수는 구조의 내부를 변경하지 않지만, 나는 오히려 하나보다, 두 가지 유형으로 끝낼 생각하지만동일한 템플릿을 병합하고 다른 함수를 대신 사용하십시오

struct cartesian {}; 
struct polar {}; 

template<unsigned int N, typename format = cartesian> 
struct Vec 
{ 
    float v[N]; 
}; 

:

나는 추적 코드가 있습니다. 이것은 필요하지 않습니다. 대신 두 가지 유형의, 나는 단지 다음과 같은 두 가지 기능이 필요하다고 선호 :

template <unsigned int N> 
Vec<N, cartesian> nrm(Vec<N, cartesian> v) 
{ 
    return v; 
} 

template <unsigned int N> 
Vec<N, polar> nrm(Vec<N, polar> v) 
{ 
    return v; 
} 

컴파일러는 형식의 템플릿 매개 변수에 따라 사용하는 기능을 결정합니다.

나는 그것을 너무 잘 설명하지 못했지만 잘하면 내 뜻을 이해할 수 있습니다. 모든 설명을 요청하십시오.

템플릿을 사용하여 수행 할 수있는 방법이 있습니까?

감사합니다.

두 개의 별도의 기능처럼 다음과 같습니다 : R Sahu를 들어


Vec<N, cartesian> nrm(Vec<N, cartesian> v) 
{ 
    float vLen = sqrt(v[0] * v[0] + v[1] * v[1]); 

    Vec<N, cartesian> result = v; 

    result[0] /= vLen; // 0 is X 
    result[1] /= vLen; // 1 is Y 

    return result; 
} 

template <unsigned int N> 
Vec<N, polar> nrm(Vec<N, polar> v) 
{ 
    Vec<N, polar> result = v; 

    result[1] = 1.0F; // 1 is length of vector 

    return result; 
} 

죄송 경우 반환 V; 혼동을 일으키고 있었으며, 오류 검사기를 조용하게 만드는 것이 었습니다. 나는 자세한 정보를 제거하고 싶었습니다.


비 템플릿 예는 도움이 될 수 있습니다 :

INT CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) 
{ 
    // I believe the code is currently being compiled down to the non-template equivalent: 
    // How I DON'T want it 

     // 2 separate type definitions 
     Vec2Car cartesianVec = { 1, 1 }; 
     Vec2Pol polarVec = { 0.785F, 1.41F }; 

     // Appropriate function is called for the type passed in 
     Vec2Car cartesianNrm = nrm(cartesianVec); 
     Vec2Pol polarNrm = nrm(polarVec); 

    // How I DO want it 

     Vec2CarPol cartesianVec = Vec<2, cartesian>(1, 1); // created with <format = cartesian>, doesn't change type definition, but compiler should know what to call below 
     Vec2CarPol polarVec = Vec<2, polar> (0.785F, 1.41F); // as above 

     // cartesianVec was created with <format = cartesian>, so use this the appropriate version of nrm(); 
     Vec2CarPol cartesianNrm = nrm(cartesianVec); 
     // polarNrm was created with <format = polar>, so use this the appropriate version of nrm(); 
     Vec2CarPol polarNrm = nrm(polarVec); 

    return EXIT_SUCCESS; 
} 
+0

왜 구조가 하나 일 필요합니까? – TAS

답변

2

그냥 두 개의 템플릿 매개 변수와 하나 개의 함수 템플릿을 사용하십시오. @cdhowie에 의해 제안

template <unsigned int N, typename format> 
Vec<N, format> nrm(Vec<N, format> v) 
{ 
    return v; 
} 

또는,

귀하의 기능이 약간 혼란 업데이트 된 질문에 대한 응답으로,

template <typename T> 
T nrm(T v) 
{ 
    return v; 
} 

업데이트를 사용합니다. 당신이 사용하는 경우 :

result[0] /= vLen; // 0 is X result[1] /= vLen; // 1 is Y 

는 내가 그 당신이 무슨 뜻인지의 가정입니다

result.v[0] /= vLen; // 0 is X 
result.v[1] /= vLen; // 1 is Y 

을 의미합니까.

당신은 사용하여 가장 재사용 가능한 코드를 가질 수 있습니다

template<unsigned int N, typename format = cartesian> 
struct Vec 
{ 
    typedef format Format; 
    float v[N]; 
}; 

void nrm(float v[], cartesian dummy) 
{ 
    float vLen = sqrt(v[0] * v[0] + v[1] * v[1]); 
    v[0] /= vLen; 
    v[1] /= vLen; 
} 

void nrm(float v[], polar dummy) 
{ 
    v[1] = 1.0F; 
} 

template <typename T> 
T nrm(T v) 
{ 
    T result = v; 
    nrm(result.v, T::Format()); 

    // Not sure what's the purpose of computing result. 
    // It is not being returned. 

    return v; 
} 
+1

아니면 멀리 가면 전체 유형을 템플릿으로 만들 수도 있습니다 : template T nrm (T v) {return v; }' – cdhowie

+0

이 경우 두 가지 형식 유형에 대해 별도의 코드를 사용하려면 어떻게해야합니까? 그리고 하나의 함수를 사용하더라도 컴파일러는 여전히 두 가지 유형의 구조를 생성합니까? – Razioark

+0

형식에 따라 코드가 어떻게 다른지를 보여줄 수 있습니까? –

0

을만큼 당신이 컴파일러에 의해 생성 된 두 구조가있을 것입니다 템플릿 매개 변수 중 하나로서 format을 가지고있다. 컴파일러가 컴파일 할 때 두 함수 중 어느 함수를 호출 할 것인지를 선택할 수있는 형식입니다.

관련 문제