'Suppressing the inline variable warning

Background
We are trying to "borrow" some code which uses an inline static variable. The code complies, without any warnings, with a C++17 compiler. However with a lower version compiler it gives the following warning:
warning: inline variables are only available with ‘-std=c++17’ or ‘-std=gnu++17’

We have been able to suppress the waning with a command-line switch but I wanted to know if there is a way to refactor the code for suppressing the warning.

I have been able to reproduce the issue with the following sample code:


Sample Code

#include <iostream>
using namespace std;

template <typename T>
class MyClass {
    T a;
public:
    void initialize(T value) {
        a = value;
    }
    
   friend ostream& operator<<(std::ostream &out, const MyClass &obj) {
       out << "Hello world " << obj.a << "!!!";
       return out;
   }
   
   /*inline*/ static MyClass<T> SENTINEL_VALUE;
   // Currently we have the undefined reference linker error
   // If we uncomment /*inline*/ we get the warning
   //
   // I know that static class member has to instantiated before
   // main() but in this case I am not sure how to do that
};


int main()
{
    MyClass<int>::SENTINEL_VALUE.initialize(56);
    cout << MyClass<int>::SENTINEL_VALUE << endl;

    MyClass<int> myObj;
    myObj.initialize(42);
    cout << myObj << endl;
 
    return 0;
}
c++


Solution 1:[1]

Inlined static member is supported only since C++17, hence the compiler's warning. There is no sense in suppressing it, if you use something prior to C++17.
All you need is to initialize your static member (within the same header file):

#include <iostream>
using namespace std;

template <typename T>
class MyClass {
    T a;
public:
    void initialize(T value) {
        a = value;
    }

    friend ostream& operator<<(std::ostream &out, const MyClass &obj) {
        out << "Hello world " << obj.a << "!!!";
        return out;
    }

    static MyClass<T> SENTINEL_VALUE;
};

template <typename T>
MyClass<T> MyClass<T>::SENTINEL_VALUE{};

So, for instance, cout << MyClass<int>::SENTINEL_VALUE << endl; outputs Hello world 0!!!.

Initializing a static member of a class template within a header file is allowed and will not lead to multiple definitions error.
Note, that this applies only to member variables of class templates (or member variable templates).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1