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

Posted

技术标签:

【中文标题】一个类不能有自己的静态 constexpr 成员实例吗?【英文标题】:Can't a class have static constexpr member instances of itself? 【发布时间】:2016-06-17 06:01:20 【问题描述】:

这段代码给了我incomplete type错误。 问题是什么?一个类是否不允许有自己的静态成员实例? 有没有办法达到同样的效果?

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

【问题讨论】:

您是专门询问constexpr 静态成员吗​​? @PiotrSkotnicki 是的。删除关键字无论如何都不会使其工作。 一旦你删除了关键字,你可以在我猜想的类之外初始化它,当它已经是一个完整的类型时 【参考方案1】:

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

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 big480,240;
    static constexpr size_impl small210,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编译

【讨论】:

【参考方案2】:

有没有办法达到同样的效果?

通过“相同的结果”,您是否特别想要constexpr-ness Size::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,"");

【讨论】:

【参考方案3】:

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

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 成员。

【讨论】:

您认为这对constexpr 成员不起作用是因为标准禁止还是因为编译器错误? @nyarlathotep108 它不起作用,因为需要内联初始化 static constexpr 成员。 this approach 呢?

以上是关于一个类不能有自己的静态 constexpr 成员实例吗?的主要内容,如果未能解决你的问题,请参考以下文章

对静态 constexpr 数据成员的未定义引用错误

为啥静态成员函数只能在类定义中声明为静态,而不能在其自己的定义中声明?

为啥在使用静态 constexpr 成员构造时 std::make_shared 与 new 不同? [复制]

Static在类中的作用

未定义的对静态constexpr char []的引用

如何初始化std :: vector的静态constexpr成员 在c ++ 11中?