【问题标题】:Can't a class have static constexpr member instances of itself?一个类不能有自己的静态 constexpr 成员实例吗?
【发布时间】: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 是的。删除关键字无论如何都不会使其工作。
  • 一旦你删除了关键字,你可以在我猜想的类之外初始化它,当它已经是一个完整的类型时

标签: c++ c++11 constexpr static-members incomplete-type


【解决方案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 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编译

【讨论】:

    【解决方案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 呢?
      猜你喜欢
      • 2012-01-21
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 2017-05-27
      • 2017-11-25
      相关资源
      最近更新 更多