Что это за сумасшедший синтаксис C ++ 11 ==> struct: bar {} foo {} ;?

168

Что это может означать в C ++ 11?

struct : bar {} foo {};
Гонки легкости на орбите
источник
Интересно, вы нашли это полезным для чего-то? Я предполагаю, что это трюк для генерации единичных экземпляров со строгим типом (с тегами).
alfC
@alfC: Не особенно полезно, нет
гонки на

Ответы:

262

Сначала мы возьмем стандартный болотный абстрактный UDT (определяемый пользователем тип):

struct foo { virtual void f() = 0; }; // normal abstract type
foo obj;
// error: cannot declare variable 'obj' to be of abstract type 'foo'

Давайте также вспомним, что мы можем создать экземпляр UDT одновременно с тем, как мы его определяем:

struct foo { foo() { cout << "!"; } };          // just a definition

struct foo { foo() { cout << "!"; } } instance; // so much more
// Output: "!"

Давайте объединим примеры и напомним, что мы можем определить UDT без имени :

struct { virtual void f() = 0; } instance; // unnamed abstract type
// error: cannot declare variable 'instance' to be of abstract type '<anonymous struct>'

Нам больше не нужны доказательства анонимного UDT, поэтому мы можем потерять чисто виртуальную функцию. Также переименовывая instanceв foo, мы остаемся с:

struct {} foo;

Приближаться.


Теперь, что если этот анонимный UDT возникнет из некоторой базы?

struct bar {};       // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof

Наконец, C ++ 11 представляет расширенные инициализаторы , так что мы можем делать такие вещи, как это:

int x{0};

И это:

int x{};

И, наконец, это:

struct : bar {} foo {};

Это безымянная структура, полученная из bar, которая создается как foo с пустым инициализатором.

Гонки легкости на орбите
источник
11
Я знаю, что следует избегать негативных комментариев по поводу языка программирования, и, возможно, это немного не по теме. Но я не понимаю, почему C ++ 0x становится еще более сложным языком, чем C ++. Кто этого хочет? Каковы преимущества языка программирования, который становится все более загадочным? Эта декларация ИМХО является еще одним примером этого. Я использую C ++ в течение многих лет, и мне все еще трудно освоить этот язык.
Джорджио
26
@ Джорджио: Почему это проблема? Что именно вас пугает? Описанная конструкция является дополнительным случаем, который допускается языком и естественно следует из его основных понятий, в этом нет ничего плохого. Это также очень ограниченная полезность. Вам никогда не придется его использовать. Тем не менее, это синтаксически логично и не сталкивается или конфликтует с чем-либо. Итак, почему это будет аргумент против языка, особенно тот, который исключительно хорошо разработан?
Керрек С.Б.
13
@ Джорджио - замечательная часть в том, что ситуация с точностью до наоборот; C ++ 0x добавляет много столь ожидаемых мощных средств, не будучи загадочным или слишком уродливым; ты хочешь отвлекаться? проверить Perl. Этот пример здесь нигде не приближается к загадочному названию.
Джин Бушуев
18
@Kerrek SB Я думаю, что в C ++ (а теперь и в C ++ 0x) слишком много разных концепций, и изучение синтаксиса и семантики затруднительно. Каждый программист (я один из них) заканчивает тем, что использовал подмножество языка, потому что есть слишком много различных способов сделать то же самое. Я не думаю, что C ++ хорошо спроектирован. Есть много специальных функций, и некоторые фундаментальные вещи, такие как надежный механизм модуля (импорт / экспорт), отсутствуют (все еще используя старый #include из C). Я думаю, что усилия C ++ 0x должны быть направлены на то, чтобы сделать C ++ меньше и проще в использовании, а не больше.
Джорджио
31
@ Джорджио: Честно говоря, любые такие усилия должны были бы работать над перестройкой C ++ с нуля, то есть созданием нового языка . И это уже было сделано ... много раз.
Гонки легкости на орбите
106

Это определяет:

  • анонимная структура,
  • который публично получен из bar
  • which ( anonymously) определяет не что иное, как то, из чего оно полученоbar
  • и, наконец, создается экземпляр, называемый "foo",
  • с пустым списком инициализатора

struct : bar {} foo {};
Frunsi
источник