我有一个头文件,其中字符串被定义为静态全局。
namespace space {
#define NAME(P) static std::string const s_##P = #P
NAME(foo); NAME(bar); //... other values
#undef NAME
}
在另一个头文件中,定义了一个枚举,并且模板特化提供了枚举和 .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
当标题包含在多个翻译单元中时,上面的代码不会链接,因为专业化定义不匹配 - 由于每个翻译单元的全局重新定义(我猜)。
在匿名命名空间中包装映射函数或添加static
关键字可以解决链接问题,但编译器会抱怨这些函数是defined but not used [-Wunused-function]
.
template<letter> static std::string const & mapping();
但是,将专业定义为constexpr
,不再有任何链接或警告问题。
template<letter> std::string const & mapping();
#define MAPPING(P1,P2) template<> constexpr std::string const & mapping<letter::P1>() { return space::s_##P2; }
我理解为什么非static
版本在链接时会失败,以及为什么static
版本可以工作并触发警告。但我不明白为什么说明constexpr
符解决了这两个问题。
您能否在标准中给出一个解释,甚至更好,一个理性的?