У меня есть файл заголовка, в котором строка определяется как stati c global.
namespace space {
#define NAME(P) static std::string const s_##P = #P
NAME(foo); NAME(bar); //... other values
#undef NAME
}
В другом заголовке определено перечисление, а специализация шаблона обеспечивает сопоставление между перечислением и строкой в 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; }
Я понимаю, почему не-1019 * версия терпит неудачу во время соединения и почему версия static
работает и вызывает предупреждения , Но я не понимаю, почему спецификатор constexpr
решает обе проблемы.
Не могли бы вы дать объяснение и, что еще лучше, рациональный стандарт?