mouse_00
mouse_00

Reputation: 683

Using inline static member instead of static member

I have a following struct:

#include <iostream>

struct Foo
{
  static int a;               // declaration
  inline static int b = 10;   // declaration and definition
};

int Foo::a = 10; // definition

int main()
{
  std::cout << Foo::a << "\n"; // --> 10
  std::cout << Foo::b << "\n"; // --> 10 (same result as Foo::b)

  return 0;
}

It is "easier" to use inline static to achieve same goal as when static is used.

Is there any case when using static members for class instead of inline static members is more preferable/required?

Note : there is an obvious case when one uses C++14 or lower standard.

Upvotes: 0

Views: 691

Answers (1)

You'd see it if you ever try to create "stateful enums". Basically, classes that capture a little data and there is a handful of "named constants" of that type that you'd want to codify as static data members. To illustrate:

struct RGB {
    inline static RGB c1{1};
    inline static RGB c2{2};
    RGB(int, int = 0, int = 0);
};

This will be ill-formed, whereas this will not:

struct RGB {
    static RGB c1;
    static RGB c2;
    RGB(int, int = 0, int = 0);
};

RGB RGB::c1{1};
RGB RGB::c2{2};

Live example

The reason is that a static data member may have an incomplete type, but it must be complete when initialised.

It will naturally pop up when playing with constexpr static members. Come C++17, they are implicitly inline, so you'd have to break the declaration from definition if you want to have them:

struct RGB {
    static const RGB c1;
    static const RGB c2;
    constexpr RGB(int, int = 0, int = 0){}
};

constexpr RGB RGB::c1{1};
constexpr RGB RGB::c2{2};

Live example

Those are valid constant, and are usable in constant expressions. But they cannot be defined inline as static data members. They are still technically inline data members on account of being constexpr, but are not defined inline (mind though that it's true prior to C++17 too, but the constant cannot be defined in a header for redefinition errors, so they are essentially unusable).

Upvotes: 1

Related Questions