At the 2016 Oulu ISO C++ Standards meeting, a proposal called Inline Variables was voted into C++17 by the standards committee.
In layman's terms, what are inline variables, how do they work and what are they useful for? How should inline variables be declared, defined and used?
The first sentence of the proposal:
” The
inline
specifier can be applied to variables as well as to functions.
The ¹guaranteed effect of inline
as applied to a function, is to allow the function to be defined identically, with external linkage, in multiple translation units. In practice that means defining the function in a header, that can be included in multiple translation units. The proposal extends this possibility to variables.
So, in practical terms the (now accepted) proposal allows you to use the inline
keyword to define an external linkage const
namespace scope variable, or any static
class data member, in a header file, so that the multiple definitions that result when that header is included in multiple translation units are OK with the linker – it just chooses one of them.
Up until and including C++14 the internal machinery for this has been there, in order to support static
variables in class templates, but there was no convenient way to use that machinery. One had to resort to tricks like
template< class Dummy >
struct Kath_
{
static std::string const hi;
};
template< class Dummy >
std::string const Kath_<Dummy>::hi = "Zzzzz...";
using Kath = Kath_<void>; // Allows you to write `Kath::hi`.
From C++17 and onwards I believe one can write just
struct Kath
{
static std::string const hi;
};
inline std::string const Kath::hi = "Zzzzz..."; // Simpler!
… in a header file.
The proposal includes the wording
” An inline static data member can be defined in the class definition and may specify a brace-or-equal-initializer. If the member is declared with the
constexpr
specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.X). Declarations of other static data members shall not specify a brace-or-equal-initializer
… which allows the above to be further simplified to just
struct Kath
{
static inline std::string const hi = "Zzzzz..."; // Simplest!
};
… as noted by T.C in a comment to this answer.
Also, the constexpr
specifier implies inline
for static data members as well as functions.