Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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; }; 
like image 984
nyarlathotep108 Avatar asked Mar 03 '16 18:03

nyarlathotep108


People also ask

Is static needed for constexpr?

A non-static data member cannot be constexpr. static constexpr int x = 5; int y; };

What is constexpr static?

static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation. Compilation and execution are disjoint and discontiguous, both in time and space. So once the program is compiled, constexpr is no longer relevant.


2 Answers

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

This doesn't work for constexpr members, however.

like image 93
Brian Bi Avatar answered Oct 07 '22 16:10

Brian Bi


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? 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,""); 
like image 27
Mike Kinghan Avatar answered Oct 07 '22 15:10

Mike Kinghan