2011-06-02 4 views
7

मैं एक विधि (ऑपरेटर(), इस मामले में एक टेम्पलेटेड क्लास D<N> बना रहा हूं, जो एन के मान के आधार पर विभिन्न प्रकार देता है।कोड डुप्लिकेशन और टेम्पलेट विशेषज्ञता (जब विशेष फ़ंक्शन में अलग-अलग रिटर्न प्रकार होते हैं)

मैं केवल दो अलग-अलग वर्ग घोषणाओं को बनाकर यह काम कर सकता हूं, लेकिन यह बहुत सारे कोड डुप्लिकेशंस की लागत पर आया था। मैं भी में आम सामान फेंकने के लिए एक आम आधार वर्ग बनाने की कोशिश की, लेकिन मैं निर्माता सही वारिस के लिए नहीं मिल सकता है और कैसे मुहावरेदार कि रूप में अच्छी तरह होगा पता नहीं है ...

#include <cstdio> 

template <int N> 
struct D{ 
    int s; 
    D(int x):s(x){} 

    int yell(int x){ 
     printf("N=%d, %d\n", N, s+x); 
     return s+x; 
    } 

    D<N-1> operator()(int x){ 
     D<N-1> d(yell(x)); 
     return d; 
    } 
}; 

template <> 
struct D<1>{ 
    int s; 
    D(int x): s(x){} 

    int yell(int x){ 
     printf("N=%d, %d\n", 1, s+x); 
     return s+x; 
    } 

    int operator()(int x){ 
     return yell(x); 
    } 
}; 


int main() 
{ 
    D<2> f(42); 
    printf("%d\n", f(1)(2)); 
    return 0; 
} 

कैसे क्या मैं अपना कोड बेहतर दिख सकता हूं?

+0

आप वापसी प्रकार मापदंडों के मूल्य पर निर्भर होने का उपयोगिता पर पुनर्विचार करने की जरूरत है। या तो इसे एक सतत पॉलीमोर्फिक रिटर्न प्रकार बनाएं, या हमेशा एक मूल प्रकार को वापस करने के लिए एक समझदार तरीका पता लगाएं। इस तरह की स्थितियों में मुझे आमतौर पर एप्लिकेशन की मूलभूत आवश्यकताओं पर वापस जाने में मदद मिलती है। – wallyk

+0

समस्या यह है कि एक निश्चित लंबाई की सूचियों को एन्कोड करने के लिए कोई अच्छा प्रकार नहीं है। टेम्पलेट ब्लैक जादू करने से मेरे छोटे डीएसएल का उपयोग करने के लिए अच्छा और टाइप-सुरक्षित भी हो सकता है। – hugomg

+0

तो आपको कुछ "संकलित समय की लंबाई" लिंक-सूची की आवश्यकता है? Std :: array/boost :: array आपके मामले के लिए उपयुक्त नहीं है? नकारात्मकता यह है कि आप इससे "सबएरे" ऑब्जेक्ट नहीं ले सकते हैं लेकिन आप "रनटाइम वैरिएबल लम्बा इंटरफ़ेस" के साथ-साथ (इटरेटर, [], पॉइंटर ...) का उपयोग कर सकते हैं। – ysdx

उत्तर

8

आप उत्सुकता से आवर्ती टेम्पलेट पैटर्न का उपयोग कर सकते हैं।

template<int N, template<int> typename D> struct d_inner { 
    D<N-1> operator()(int x) { 
     return D<N-1>(static_cast<D<N>*>(this)->yell(x)); 
    } 
}; 
template<template<int> typename D> struct d_inner<1, D> { 
    int operator()(int x) { 
     return static_cast<D<1>*>(this)->yell(x); 
    } 
}; 

template <int N> struct D : public d_inner<N, D> { 
    int s; 
    D(int x):s(x){} 

    int yell(int x){ 
     printf("N=%d, %d\n", N, s+x); 
     return s+x; 
    } 
}; 

ऐसा नहीं है कि मैं इस विशेष वस्तु के टेम्पलेट के उपयोगिता या उद्देश्य को देखता हूं, यह आसानी से नहीं हो सकता है।

+0

+1 "यह नहीं कि मैं इस विशेष वस्तु के टेम्पलेट के उपयोगिता या उद्देश्य को देखता हूं, यह आसानी से" – fedvasu

4

मैं इसे बेहतर लग रही है यकीन नहीं है: लेकिन यह स्रोत कोड दोहराव से बचा जाता है:

// Find a name for this ... 
template<int N, template<int M> class X> 
struct foo { 
    typedef X<N> type; 
}; 
template< template<int M> class X > 
struct foo<0,X> { 
    typedef int type; 
}; 

template <int N> 
struct D{ 
    int s; 
    D(int x):s(x){} 

    int yell(int x){ 
    printf("N=%d, %d\n", N, s+x); 
     return s+x; 
    } 

    typename foo<N-1,D>::type 
    operator()(int x){ 
    return typename foo<N-1,D>::type(yell(x)); 
    } 
}; 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^