2012-09-05 24 views
5

में ifdef की मैं एक सी ++ वर्ग के अंदर निम्नलिखित कोड है:टर्निंग # सी में एक टेम्पलेट metaprogram ++

class Features 
{ 
    #define Feature_Size_A 12345 
    #define Feature_Size_B 45678 
    #define Feature_Size_C 78901 
    //#define Feature_Size_D 14725 

    const int Feature_Sum = 0 
    #ifdef Feature_Size_A 
     + Feature_Size_A 
    #endif 
    #ifdef Feature_Size_B 
     + Feature_Size_B 
    #endif 
    #ifdef Feature_Size_C 
     + Feature_Size_C 
    #endif 
    #ifdef Feature_Size_D 
     + Feature_Size_D 
    #endif 
     ; 

    #ifdef Feature_Size_A 
     static float Feature_A[Feature_Size_A]; 
    #endif 
    #ifdef Feature_Size_B 
     static float Feature_B[Feature_Size_B]; 
    #endif 
    #ifdef Feature_Size_C 
     static float Feature_C[Feature_Size_C]; 
    #endif 
    #ifdef Feature_Size_D 
     static float Feature_D[Feature_Size_D]; 
    #endif 
}; 

मैं सुविधाओं की टिप्पणी करने के लिए, लाइन 4 की तरह, संकलन और विभिन्न परीक्षण चलाने के लिए इस्तेमाल किया। लेकिन अब मैं कक्षा को एक टेम्पलेट के रूप में रखना चाहता हूं, इसलिए मैं एक ही कार्यक्रम में चालू या बंद विभिन्न सुविधाओं के साथ कई संस्करणों को तुरंत चालू कर सकता हूं।

मैं कुछ इस तरह की सोच रहा हूँ:

template <bool Feature_A, bool Feature_B, bool Feature_C, bool Feature_D> 
class Features 
{ 
    ... 
}; 

Features<true, true, true, false> f; 

मैं बढ़ावा :: एमपीएल के साथ करने की कोशिश की: वेक्टर के लेकिन मैं कठोरता से संघर्ष कर रहा हूँ।

बीटीडब्ल्यू: यह पूरा कोड नहीं है। मूल कोड में 25 विशेषताएं हैं।

मैं मैक्रो को शामिल नहीं :-)

+0

सुविधाओं का उपयोग कैसे किया जाता है? क्या वे 'फीचर्स' क्लास के बाहर से पहुंचे हैं? क्या उन्हें किसी विशिष्ट नाम से सुलभ होना चाहिए, या अनुक्रमित पहुंच स्वीकार्य है? क्या वे सभी अरणें तैरते हैं? –

उत्तर

3

प्रकार सूचियों इस समस्या को हल करने के लिए इस्तेमाल किया जा सकता।

template<unsigned num, unsigned size, typename T> 
class Feature : public T 
{ 
public: 
    static float feature[size]; 
    static const unsigned int feature_sum = size + T::feature_sum; 
}; 
template<unsigned num, unsigned size, typename T> 
float Feature<num, size, T>::feature[size]; 
class Tail { 
public: 
    static const unsigned feature_sum = 0; 
}; 

template<unsigned num, unsigned size, typename T> 
float* get_feature_arr(Feature<num, size, T>& ref) 
{ 
    return ref.feature; 
} 

int main() { 
    Feature<1, 12345, Feature<2, 45678, Feature<4, 78901, Tail>>> TripleFeatures; 
    auto first = get_feature_arr<1>(TripleFeatures); 
    auto third = get_feature_arr<4>(TripleFeatures); 
    auto size = TripleFeatures.feature_sum; 
} 

इसका उपयोग किसी भी सुविधा तक पहुंचने के लिए भी किया जा सकता है, भले ही अन्य सुविधाएं क्या हैं या सूची में नहीं हैं।

संपादित करें: मैंने कुछ विवरणों को नामांकित किया है, जैसे कि सरणी को परिभाषित नहीं करना और पहचानकर्ता के रूप में "3 फीचर" रखने का प्रयास करना। ले तय कोड जीसीसी 4.7.1 संकलित करता है।

+0

आईएमएचओ: एक बहुत ही शानदार समाधान। यह वही है जो मैं शुरू में देख रहा था। – PanicSheep

1

हर विचार के लिए आभारी हूँ क्यों स्थिर आवंटित सरणियों का उपयोग नहीं?

#include <stdio.h> 

template <bool Feature_A, bool Feature_B, bool Feature_C, bool Feature_D> 
class Features 
{ 
    static const int Feature_Size_A = 12345; 
    static const int Feature_Size_B = 45678; 
    static const int Feature_Size_C = 78901; 
    static const int Feature_Size_D = 14725; 
    static const int Feature_Sum = 0 
     + Feature_A ? Feature_Size_A : 0 
     + Feature_B ? Feature_Size_B : 0 
     + Feature_C ? Feature_Size_C : 0 
     + Feature_D ? Feature_Size_D : 0 
    ; 

public: 
    static float Feature_Vector_A[Feature_A ? Feature_Size_A : 0]; 
    static float Feature_Vector_B[Feature_B ? Feature_Size_B : 0]; 
    static float Feature_Vector_C[Feature_C ? Feature_Size_C : 0]; 
    static float Feature_Vector_D[Feature_D ? Feature_Size_D : 0]; 
}; 

Features<true, true, true, true> f1; 
Features<true, true, true, false> f2; 

int main() 
{ 
    printf("%d %d\n", sizeof(f1.Feature_Vector_D), sizeof(f2.Feature_Vector_D)); 
} 

आउटपुट:

58900 0 
+0

क्योंकि अब 'feature_vector_a' मौजूद है, भले ही' feature_d' सत्य है। – Puppy

+0

@DeadMG मेरा अपडेट देखें – user1202136

+0

0 आकार का सरणी केवल सी ++ कंपाइलर्स को अनुरूप बनाने पर संकलक त्रुटि का मतलब है। यदि आपने कोई सुविधा मौजूद नहीं है तो आपने इसे संकलित करने में विफल होने के अलावा कुछ भी हल नहीं किया है। – Puppy

1

यह स्पष्ट नहीं है कि वास्तव में क्या सुविधाओं वास्तव में हो जाएगा, लेकिन यहाँ एक समाधान है कि आप conditionnaly के सदस्य कार्यों के साथ-साथ सदस्य डेटा शामिल की अनुमति देता है:

namespace mpl = boost::mpl; 

// Define your features 
struct FeatureA 
{ 
    static const int size = 12345; 
    static float Feature_A[size]; 

    static void methodA() {} 
}; 
float FeatureA::Feature_A[12345]; 

struct FeatureB 
{ 
    static const int size = 45678; 
    static char Feature_B[size]; // possibly different types of data (?) 

    static void methodB() {} 
}; 
float FeatureB::Feature_B[45678]; 

struct FeatureC 
{ 
    static const int size = 78901; 
    static int Feature_C[size]; 

    static void methodC() {} 
}; 
float FeatureC::Feature_C[78901]; 


// Helper metafunction 
template <typename T> 
struct get_size 
    : mpl::int_<T::size> 
{}; 


template <typename FeaturesSeq> 
struct Features_impl 
    : mpl::inherit_linearly< 
     FeaturesSeq, 
     mpl::inherit<mpl::_, mpl::_> 
    >::type 
{ 
    static const int Feature_Sum = 
     mpl::accumulate< 
      FeaturesSeq, 
      mpl::int_<0>, 
      mpl::plus< 
       mpl::_1, 
       get_size<mpl::_2> 
      > 
     >::type::value; 
}; 

template <typename... F> 
using Features = Features_impl<mpl::vector<F...>>; 


#include <iostream> 

int main() 
{ 
    typedef Features<FeatureA, FeatureC> F; 

    std::cout << F::Feature_Sum << '\n'; 

    F::Feature_A[0] = 12.0f; 
    F::methodA(); 

    F::methodC(); 
} 

अपने सभी सुविधाओं का वास्तव में सिर्फ नाव रखते हैं

: सरणियों, अपने उदाहरण के रूप में, आप एक सामान्य Feature वर्ग

template <int Size> 
struct Feature 
{ 
    static float data[Size]; 
}; 
template <int Size> 
float Feature::data[Size]; 

और दुकान इस वर्ग की विशेषज्ञताओं एमपीएल वैक्टर में उपयोग कर सकते हैं

इन तथाकथित सुविधाओं के उद्देश्य के बारे में अधिक जानकारी के बिना, एक और पूर्ण उत्तर प्रदान करना मुश्किल है।