I have a header file where string are defined as static global.
namespace space {
#define NAME(P) static std::string const s_##P = #P
NAME(foo); NAME(bar); //... other values
#undef NAME
}
In another header, an enum is defined and a template specialization provides the mapping between the enum and a string in space.
enum class letter { alpha, beta };
template<letter> std::string const & mapping();
#define MAPPING(P1,P2) template<> std::string const & mapping<letter::P1>() { return space::s_##P2; }
MAPPING(alpha,foo)
MAPPING(beta,bar)
#undef MAPPING
The above code doesn't link when the header is included in more than one translation unit because the specializations definitions do not match - due to global redefinition per translation unit (I guess).
Wrapping the mapping functions in anonymous namespace or adding static keyword solves the linking issue but then the compiler complains that the functions are defined but not used [-Wunused-function].
template<letter> static std::string const & mapping();
But, defining the specializations as constexpr, there is no longer any link or warning issue.
template<letter> std::string const & mapping();
#define MAPPING(P1,P2) template<> constexpr std::string const & mapping<letter::P1>() { return space::s_##P2; }
I understand why the non-static version fails at link time and why the static version works and triggers warnings. But I don't understand why the constexpr specifier solves both issues.
Can you please give an explanation and even better, a rational in the standard ?