一个类不能有自己的静态 constexpr 成员实例吗?



这段代码给了我不完整的类型错误。问题出在哪里?不允许类具有自身的静态成员实例吗?有没有办法达到相同的结果?

struct Size
{
    const unsigned int width;
    const unsigned int height;
    static constexpr Size big = { 480, 240 };
    static constexpr Size small = { 210, 170 };
private:
    Size( ) = default;
};

允许类具有相同类型的静态成员。但是,类在其定义结束之前是不完整的,并且不能使用不完整类型定义对象。您可以声明具有不完整类型的对象,并在以后完成的位置(在类外部)定义它。

struct Size
{
    const unsigned int width;
    const unsigned int height;
    static const Size big;
    static const Size small;
private:
    Size( ) = default;
};
const Size Size::big = { 480, 240 };
const Size Size::small = { 210, 170 };

在这里看到这个: http://coliru.stacked-crooked.com/a/f43395e5d08a3952

但是,这不适用于constexpr成员。

有没有办法达到相同的结果?

通过"相同的结果",您是否特别打算constexprSize::bigSize::small?在这种情况下,也许这已经足够接近了:

struct Size
{
    const unsigned int width = 0;
    const unsigned int height = 0;
    static constexpr Size big() {
        return Size { 480, 240 };
    }
    static constexpr Size small() {
        return Size { 210, 170 };
    }
private:
    constexpr Size() = default;
    constexpr Size(int w, int h )
    : width(w),height(h){}
};
static_assert(Size::big().width == 480,"");
static_assert(Size::small().height == 170,"");

作为一种解决方法,您可以使用单独的基类,该基类在定义派生类中的常量时是完整的。

struct size_impl
{
//data members and functions here
    unsigned int width;
    unsigned int height;
};

struct size:  public size_impl
{
//create the constants as instantiations of size_impl
    static constexpr size_impl big{480,240};
    static constexpr size_impl small{210,170};
//provide implicit conversion constructor and assignment operator
    constexpr size(const size_impl& s):size_impl(s){}
    using size_impl::operator=;
//put all other constructors here
};
//test:
constexpr size a = size::big;

如果需要,可以将基类放在单独的命名空间中以隐藏其定义。

代码使用 clang 和 gcc 编译

另一种可能的解决方法是延迟使用模板来延迟对size定义的需要。

template<typename...>
class size {
public:
    template<typename...>
    static constexpr auto big = size{480, 240};
    template<typename...>
    static constexpr auto small = size{210, 170};
    unsigned const width;
    unsigned const height;
private:
    constexpr size() = default;
    constexpr size(unsigned w, unsigned h)
        : width{w}, height{h} {}
};
static_assert(noexcept(size<>::big<>), "");

现场示例

最新更新