2

有没有办法强制派生类型static constexpr在 C++ 中定义 a?我有一个基类,我想强制每个派生类定义一个static const bool has_property.

我尝试使用 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没有初始化。

我怎样才能做到这一点?

4

2 回答 2

5

我们可以将 a 插入static_assert到 的构造函数中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");
    }
};

此检查仅在派生类被实例化使用默认构造函数时起作用Base。该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.
于 2012-07-08T08:24:27.437 回答
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 > {
};

[更新1] 对于数组 - 而不是传递单个布尔值 - 传递包含值的结构:

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 > {
};
于 2012-07-08T10:55:23.663 回答