简体   繁体   English

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

[英]Can't a class have static constexpr member instances of itself?

This code is giving me incomplete type error.这段代码给了我不完整的类型错误。 What is the problem?问题是什么? Isn't allowed for a class to have static member instances of itself?不允许一个类有自己的静态成员实例吗? Is there a way to achieve the same result?有没有办法达到同样的结果?

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

A class is allowed to have a static member of the same type.一类允许具有相同类型的静态成员。 However, a class is incomplete until the end of its definition, and an object cannot be defined with incomplete type.然而,一个类在定义结束之前是不完整的,并且一个对象不能定义为不完整的类型。 You can declare an object with incomplete type, and define it later where it is complete (outside the class).你可以声明一个不完整类型的对象,然后在它完整的地方(在类之外)定义它。

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

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

This doesn't work for constexpr members, however.但是,这不适用于constexpr成员。

Is there a way to achieve the same result?有没有办法达到同样的结果?

By "the same result", do you specifically intend the constexpr -ness of Size::big and Size::small ?通过“相同的结果”,您是否特别打算使用Size::bigSize::smallconstexpr In that case maybe this would be close enough:在那种情况下,这可能足够接近:

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,"");

As a workaround you can use a separate base class which definition is complete when defining the constants in the derived class.作为一种解决方法,您可以使用单独的基类,在派生类中定义常量时,该基类的定义是完整的。

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;

You can put the base class in a separate namespace to hide its definition if you want to.如果需要,您可以将基类放在单独的命名空间中以隐藏其定义。

The code compiles with clang and gcc代码用 clang 和 gcc 编译

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM