2012-07-08 88 views
1

有沒有辦法強制派生類型在C++中定義static constexpr?我有一個基類,我想強制每個派生類定義一個static const bool has_propertyC++派生類型必須定義靜態constexpr

我試着用CRTP這樣做(讓每個派生類都有自己的static const):

template <typename T, class MyClass> 
struct Base { 
    T data; 
    static constexpr bool has_property; 
}; 

template <typename T> 
struct Derived : public Base<T, Derived<T> > { 
    static constexpr bool has_property = false; 
}; 

但是,編譯器抱怨Base::has_property未初始化。

我該如何做到這一點?

+1

你想要'靜態constexpr'(C++ 11)或'靜態const'(C++ 03)嗎? – iammilind 2012-07-08 07:57:07

+1

你錯過了'constexpr'的類型(可能是'bool')。 – juanchopanza 2012-07-08 07:57:48

+0

@iammilind我想要'static const',並認爲有一些好處可以讓你在定義中初始化'static constexpr'。 ? – user 2012-07-08 08:02:18

回答

4

我們可以插入一個static_assertBase構造:當派生類實例化,Base默認構造函數用於

template <typename T, class MyClass> 
struct Base { 
    T data; 

    Base() { 
     static_assert(std::is_same< 
         typename std::decay< 
          decltype(MyClass::has_property) 
         >::type, bool 
         >::value, 
         "Must be a bool"); 
     static_assert(MyClass::has_property || true, 
         "Must be constexpr"); 
    } 
}; 

該檢查將只工作。目前,constexpr檢查在g ++ 4.7中不起作用。


或者,你可以使用一種類型的特徵,而不是一個constexpr靜態成員,例如

template <typename T> 
struct has_property; 

template <typename T> 
struct has_property<Derived<T>> : std::true_type {}; 

// use as: has_property<X>::value. 
+0

感謝您的想法。我實際上試圖強制子類型定義一個指定長度的布爾靜態數組(問題中的布爾只是一個例子)。有什麼想法嗎? – user 2012-07-10 07:26:07

+0

@Oliver:然後比較'bool [n]'而不是'bool'。 – kennytm 2012-07-10 07:59:20

2

也許增加has_property價值,您的基本模板參數會爲你工作:

template <typename T, class MyClass, bool hasPropertyValue> 
struct Base { 
    T data; 
    static constexpr bool has_property = hasPropertyValue; 
}; 

template <typename T> 
struct Derived : public Base<T, Derived<T>, false > { 
}; 

[UPDATE1] 對於數組 - 而不是通過單一的布爾值 - 包含通結構值:

template <typename T, class MyClass, class MyClassPropertyValues> 
struct Base { 
    T data; 
    static constexpr bool has_property[MyClassPropertyValues::length]; 
}; 
template <typename T, class MyClass, class MyClassPropertyValues> 
constexpr bool Base<T, MyClass, MyClassPropertyValues>:: 
has_property[MyClassPropertyValues::length] = MyClassPropertyValues::initValues; 

struct DerivedPropertyValues { 
    static constexpr size_t length = 3; 
    static constexpr bool initValues[length]; 
};  
constexpr bool DerivedPropertyValues::initValues[length] = { true, false, true }; 

template <typename T> 
struct Derived : public Base<T, Derived<T>, DerivedPropertyValues > { 
}; 
+0

好主意,但我實際上需要一個bools數組 - 如果我將該數組作爲模板參數傳遞,您認爲它仍然可讀嗎? – user 2012-07-10 07:27:56

+0

用屬性數組添加更新。包含數組的布爾是相當可讀我相信... – PiotrNycz 2012-07-10 13:31:21