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).