lundi 30 décembre 2019

Static specialized template members in C++17 - why there is difference between GCC and MSVC?

My question is about template static members not not about template static functions.

Prior to C++17, when building with GCC and having includes in several CPP files, to avoid "multiple definitions" linker errors of static specialized template members similarly to static functions, they have to be either defined as inline or defined in CPP files (see this).

I have reasons not to define static template members in CPP files so I have to use inline. But to do this I have to switch in both GCC and VS2017 to C++17 because static template inline functions are allowed after C++11 but static template inline members are allowed only after C++17.

But this whole problem does not exist at all in MSVC. This is demonstrated below:


ClassT.h:

template <typename T>
class ClassT
{
public:
    static const T  CC;     
};

template<> const char ClassT<char>::CC = '\\';


Main.cpp:

#include "ClassT.h"

int main()
{
    return 0;
}


Test.cpp:

#include "ClassT.h"

This will compile and links without warnings in MSVC but will not compile with GCC giving linker error: "multiple definition of `ClassT::CC'.

MSVC linker figures out that there is more than one definition and takes only one of them while GCC obviously fails to do this. To solve it for GCC one have to add inline:

template <typename T>
class ClassT
{
public:
    inline static const T  CC;     
};

template<> inline const char ClassT<char>::CC = '\\';

Which however forces to switch to C++17 otherwise will not compile with MSVC.

I wonder which one is correct and according to specification in this case GCC or MSVC linker and how exactly the latter resolves such static members without the inline definition?

Aucun commentaire:

Enregistrer un commentaire