2014-02-22 2 views
1

템플릿 메타 프로그래밍을 많이 사용하는 소프트웨어에서는 템플릿 클래스가 클래스 템플릿을 인수로 사용하여 해당 동작의 특정 측면을 정의합니다. 아주 간단한 예로서 두 개의 다른 숫자에서 수를 계산하기 위해 수식을 사용해야하는 클래스 FormulaUser이 있다고 가정하고 특정 수식을 템플릿 매개 변수로 지정해야합니다. 또한 수식은 해당 데이터 유형 (float 또는 double)과 관련하여 공개되어야합니다. 예를 들어 :최소한의 상용구를 사용하여 매개 변수화 된 클래스 템플릿을 구현하는 방법

template <template<typename> class Formula, typename FpType> 
struct FormulaUser { 
    using TheFormula = Formula<FpType>; 

    void some_function() 
    { 
     FpType x = 1; 
     FpType y = 2; 
     FpType result = TheFormula::calculate(x, y); 
    } 
}; 

template <typename FpType> 
struct AddFormula { 
    static FpType calculate (FpType x, FpType y) { return x + y; } 
}; 

// composition: 
using TheFormulaUser = FormulaUser<AddFormula, float>; 

이 아니라 너무 많은 수식 자체가 FormulaUser에 전달되기 전에 정의 된 매개 변수를 가질 필요가있을 때, OK입니다. (

  • 구성 못생긴 :이 코드에 대해 좋아하지 않는 무엇

    template <float A, float B, float C> 
    struct LinearFormula { 
        template <typename FpType> 
        struct Formula { 
         static FpType calculate (FpType x, FpType y) { return A + B*x + C*y; } 
        }; 
    }; 
    
    // composition: 
    using TheFormulaUser = FormulaUser<LinearFormula<1.0, 2.0, 3.0>::template Formula, float>; 
    

    은 다음과 같습니다 예를 들어, LinearFormula는 (의 포인트 유형 부동 템플릿 매개 변수가 될 수 없다는 사실을 무시하자) ::template Formula part).

  • LinearFormula의 고기는 두 번 들여 씁니다.

더 멋지게 만들 수있는 방법이 있습니까?

UPDATE

I는 두 레벨 (화학식 상수 및 FpType)에 화학식 파라미터를 분리하고자하는 이유는 첫번째 세트의 사람들은 사용자 구성의 일부임을 상기 제 2 세트에 해당하면서 수식을 사용하는 수업에서 제공됩니다. 음, FpType도 사용자 구성으로 끝나지 만 모든 수식에 대해 동일해야합니다. 이 복잡한 구성은 다음을 보여줍니다.

using MyProgram = Program< 
    float, // FpType 
    AddFormula, // Formula for something 
    LinearFormula<2.0, 5.3, 5.3>, // Formula for something else 
    QuadraticFormula<.....>, // For something else... 
    ExponentialAveraging< // AveragingType 
     0.6 // SmoothingFactor 
    > 
>; 

그래서 FpType을 루트 클래스에 지정하면 다른 모든 것에 전파됩니다.

이러한 예는 인공적이지만 문제를 설명해야합니다. 나는 구성이 필요 이상으로 더 많은 보일러 판을 가지기를 원하지 않습니다 (특히, float 상수는 실제로는 위와 같이 지정할 수 없습니다 ...).

마지막으로 성능 메타 데이터와 기존 코드와의 일관성을 위해 템플릿 메타 프로그래밍을 사용해야합니다.

+0

이중 들여 쓰기와':: template'은 중첩의 결과이지만 중첩을 유도하거나 유효한 그림을 제공하지 않았습니다. 해결책은 분명히 중첩을 피하는 것이지만,이 정보를 바탕으로 문제를 해결하는 데 도움을 줄 수는 없습니다. – Potatoswatter

+0

@Potatoswatter 업데이트보기 –

+1

표현 템플릿으로 해결되는 솔루션 공간에있는 것처럼 보입니다. 어떻게 완료되었는지 살펴볼 수 있습니다. 구성은 함수 오버로딩에 의한 것이지 중첩 템플릿 인수 목록에 의한 것이 아닙니다. 어쨌든, 제 스타일은 그렇지만 TMP의 복잡성에 관계없이 저는 개인적으로 템플릿 템플릿 매개 변수를 사용자에게 노출시키지 않습니다.거의 항상 더 나은 대안이 있습니다. – Potatoswatter

답변

0

나는 여러분의 예제가 다소 고안된 것을 알고 있지만, 템플릿 템플릿 매개 변수와 중첩에 대한 이유를 알 수 없습니다. 그래서 제 제안은 그것을 제거하고 수식 수준에서 모든 매개 변수 유형 매개 변수화를 수행하는 것입니다. 이것은 '더 깔끔하고'덜 중첩 된 솔루션을 만들지 만 유용하지는 않습니다. 부동 소수점 템플릿 매개 변수를 정책 클래스로 옮겼습니다.

template <class Formula> 
struct FormulaUser 
{ 
    using param_type = typename Formula::param_type; 

    param_type some_function() 
    { 
     param_type x = 1; 
     param_type y = 2; 
     return Formula::calculate(x, y); 
    } 
}; 

template <typename FpType> 
struct AddFormula 
{ 
    using param_type = FpType; 
    static FpType calculate(FpType x, FpType y) { return x + y; } 
}; 

using TheFormulaUser = FormulaUser<AddFormula<float>>; 

struct SomeCoefficients 
{ 
    static float A() 
    { 
     return 1.0; 
    } 
    static float B() 
    { 
     return 2.0; 
    } 
    static float C() 
    { 
     return 3.0; 
    } 
}; 

template <typename FPType, typename LinearPolicy> 
struct LinearFormula 
{ 
    using param_type = FPType; 
    static FPType calculate(FPType x, FPType y) 
    { 
     return LinearPolicy::A() + LinearPolicy::B() * x + LinearPolicy::C() * y; 
    } 
}; 

// composition: 
using TheFormulaUser2 = FormulaUser<LinearFormula<float, SomeCoefficients>>; 
+0

FormulaUser에서 FpType을 한 번 지정할 수 있어야하므로 유용하지 않습니다. FormulaUser는 FpType에 열려있는 많은 클래스를 사용할 수 있습니다. –

+0

분명히 나는 ​​TheFormulaUser = FormulaUser ;을 사용하여 TheFormulaUser = FormulaUser >;를 사용하는 구문으로 옮길 것을 제안합니다. 인스턴스화의 관점에서는 그다지 중요하지 않습니다. 이게 도움이되지 않는다면 어떤 식 으로든 나는 아이디어가 없어. –

+0

FormulaUser 구성은 사용자 구성 일종의 파일로 이루어지며 많은 수식 선택 항목에 대해 모든 float 매개 변수를 포함하는 것은 좋지 않습니다. –