Почему мы не можем инициализировать члены внутри структуры?
пример:
struct s {
int i = 10;
};





Если вы хотите инициализировать элементы нестатический в structдекларация:
В C++ (не C) structs почти синонимичны классам и могут иметь элементы, инициализированные в конструкторе.
struct s {
int i;
s(): i(10)
{
}
};
Если вы хотите инициализировать пример:
В C или C++:
struct s {
int i;
};
...
struct s s_instance = { 10 };
C99 также имеет функцию, называемую назначенными инициализаторами:
struct s {
int i;
};
...
struct s s_instance = {
.i = 10,
};
Существует также расширение GNU C, которое очень похоже на назначенные инициализаторы C99, но лучше использовать что-то более переносимое:
struct s s_instance = {
i: 10,
};
Не могли бы вы уточнить свой последний пример?
Edit2: Этот ответ был написан в 2008 году и относится к C++ 98. Правила инициализации членов были изменены в последующих версиях языка.
Редактировать: Первоначально вопрос был помечен как c++, но на плакате говорилось, что он касается c, поэтому я повторно пометил вопрос, но оставляю ответ ...
В C++ struct - это просто class, который по умолчанию используется для public, а не для private для членов и наследования.
C++ позволяет инициализировать только неотъемлемые члены static const в строке, другие члены должны быть инициализированы в конструкторе, или если struct является POD в списке инициализации (при объявлении переменной).
struct bad {
static int answer = 42; // Error! not const
const char* question = "what is life?"; // Error! not const or integral
};
struct good {
static const int answer = 42; // OK
const char* question;
good()
: question("what is life?") // initialization list
{ }
};
struct pod { // plain old data
int answer;
const char* question;
};
pod p = { 42, "what is life?" };
Это уже давно устарело ... Теперь это позволяет C++!
Прямой ответ заключается в том, что определение структуры объявляет тип, а не переменную, которую можно инициализировать. Ваш пример:
struct s { int i=10; };
Здесь не объявляется никакая переменная - он определяет тип. Чтобы объявить переменную, вы должны добавить имя между } и ;, а затем инициализировать его после этого:
struct s { int i; } t = { 10 };
Как отметили Checkers, в C99 вы также можете использовать назначенные инициализаторы (что является прекрасным улучшением - однажды C догонит другие функции, которые имел Fortran 66 для инициализации данных, в первую очередь повторяя инициализаторы определенное количество раз). Эта простая структура не дает никаких преимуществ. Если у вас есть структура, скажем, с 20 членами и вам нужно только инициализировать один из них (скажем, потому что у вас есть флаг, который указывает, что остальная часть структуры инициализирована или нет), это более полезно:
struct s { int i; } t = { .i = 10 };
Эта нотация также может использоваться для инициализации объединений, чтобы выбрать, какой элемент объединения инициализируется.
Мы не можем инициализировать, потому что, когда мы объявили любую структуру, отличную от того, что мы делаем, просто сообщите компилятору об их присутствии, т.е. для этого не выделена память, и если мы инициализируем член без памяти для этого. Обычно то, что происходит, когда мы инициализируем любую переменную, которая зависит от места, где мы объявили переменную, компилятор выделяет память для этой переменной.
int a = 10;
Итак, какая память требуется для хранения этих данных, но в случае структуры памяти нет, поэтому ее невозможно инициализировать.
Хотя ваш ответ кажется приятным, вы должны попытаться сделать его более ясным, например, исправив свои формулировки!
Обратите внимание, что в C++ 11 теперь разрешено следующее объявление:
struct s {
int i = 10;
};
Это старый вопрос, но он занимает высокое место в Google и с тем же успехом может быть прояснен.
Что именно он делает? Сравнимо ли это со значением инициализации конструктора по умолчанию? Если да: будет ли это присвоение выполняться, если вызывается конструктор копирования или перемещения?
Он в основном вставляется в список инициализации членов ваших конструкторов, если член не инициализирован явно.
Это где-нибудь задокументировано?
Как вы сказали, это просто член, а не переменная. Когда вы объявляете переменную, компилятор также предоставляет пространство памяти для тех переменных, куда вы можете поместить значения. В случае a члена структуры компилятор не предоставляет для него место в памяти, поэтому вы не можете присваивать значения членам структуры, если не создадите переменную этого типа структуры.
Потому что это определение, а не декларация