Есть несколько вопросов о переполнении стека в духе «почему я не могу инициализировать статические элементы данных в классе в C++». Большинство ответов цитируются из стандарта, говорящего вам, что вы можете сделать; те, кто пытается ответить почему, обычно указывают на ссылку (теперь кажущуюся недоступной) [EDIT: на самом деле она доступна, см. ниже] на сайте Страуструпа, где он заявляет, что разрешение инициализации статических членов в классе приведет к нарушать правило одного определения (ODR).
Однако эти ответы кажутся слишком упрощенными. Компилятор прекрасно справляется с проблемами ODR, когда захочет. Например, рассмотрим следующее в заголовке C++:
struct SimpleExample
{
static const std::string str;
};
// This must appear in exactly one TU, not a header, or else violate the ODR
// const std::string SimpleExample::str = "String 1";
template <int I>
struct TemplateExample
{
static const std::string str;
};
// But this is fine in a header
template <int I>
const std::string TemplateExample<I>::str = "String 2";
Если я создаю экземпляр TemplateExample<0>
в нескольких единицах трансляции, срабатывает магия компилятора/компоновщика, и я получаю ровно одну копию TemplateExample<0>::str
в конечном исполняемом файле.
Итак, мой вопрос: учитывая, что компилятор, очевидно, может решить проблему ODR для статических членов классов-шаблонов, почему он не может сделать это и для классов, не являющихся шаблонами?
EDIT: ответы на часто задаваемые вопросы Stroustrup доступны здесь. Соответствующее предложение:
Однако, чтобы избежать сложных правил компоновщика, C++ требует, чтобы каждый объект имел уникальное определение. Это правило было бы нарушено, если бы С++ разрешал определение сущностей внутри класса, которые необходимо хранить в памяти как объекты.
Однако кажется, что эти «сложные правила компоновщика» существуют и используются в случае шаблона, так почему бы не использовать его и в простом случае?
inline static int x[] = {1, 2, 3};
. См. en.cppreference.com/w/cpp/language/static#Static_data_members. - person Vladimir Reshetnikov   schedule 15.02.2018