2012-09-05 38 views
5

我有一個C++類中下面的代碼:談到的#ifdef到在C模板元編程++

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; 

我試着用升壓:: MPL:矢量的,但我掙扎嚴厲。

順便說一句:這不是完整的代碼。原始代碼有25個功能。

我很感激每一個想法不涉及宏:-)

+0

如何使用這些功能?他們是從'Features'類的外部訪問的嗎?它們應該可以用特定的名稱訪問還是可以被索引訪問?他們都是浮法陣列嗎? –

回答

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; 
} 

這也可以被用來訪問任何功能,無論什麼其他的特點是或不是在列表中。

編輯:我列舉了一些細節,如未定義數組並嘗試將「3features」作爲標識符。勒固定。代碼編譯GCC 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大小的數組只是意味着符合C++編譯器的編譯器錯誤。你沒有解決任何問題,除非它不能編譯,如果任何功能不存在。 – 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]; 

和存儲專長爲MPL載體:

typedef mpl::vector<Feature<1234>, Feature<5678>> Features; 

mpl::at_c<Features, 0>::type::data[0] = 12.0f; 
// could be encapsulated into a helper function 

沒有關於這些所謂功能的更多信息,很難提供更完整的答案。