Есть несколько вопросов о переполнении стека по строкам "почему я не могу инициализировать статические члены данных в классе в С++". Большинство ответов цитирует со стандартного сообщения о том, что вы можете сделать; те, которые пытаются ответить, почему обычно указывают на ссылку (теперь, казалось бы, недоступную) [EDIT: на самом деле она доступна, см. ниже] на сайте Stroustrup, где он утверждает, что разрешение инициализации статических членов в классе нарушало бы правило одного определения (ODR).
Однако эти ответы кажутся чрезмерно упрощенными. Компилятор отлично справляется с проблемами ODR, когда захочет. Например, рассмотрите следующее в заголовке С++:
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 для статических членов классов шаблонов, почему это не может быть сделано для классов без шаблонов?
РЕДАКТИРОВАТЬ. Ответ на часто задаваемые вопросы в Stroustrup здесь. Соответствующее предложение:
Однако, чтобы избежать сложных правил компоновщика, С++ требует, чтобы каждый объект имел уникальное определение. Это правило будет нарушено, если С++ допускает определение класса в классе, которое необходимо сохранить в памяти как объекты
Однако, похоже, что эти "сложные правила компоновщика" существуют и используются в случае шаблона, так почему бы и в простом случае?