В C++ объявление и инициализацию переменной области с фигурными скобками вместо оператора присваивания

Я смотрю основной доклад Бьярне Страуструпа о стиле C++11 (ссылке) (00:35:30) и у меня возникли проблемы с пониманием следующего (код скопирован с слайда):

void f(int n, int x)
{
      Gadget g {n};
      // ...
      if (x<100) throw std::run_time_error{"Weird!"};
      if (x<200) return;
      // ...
}

Я попытался скомпилировать этот код, используя структуру, а также объект, но в обоих случаях компилятор говорит мне, что он ожидает ';' в конце объявления Gadget g и не скомпилируется.

поэтому мои вопросы:

  • правильно ли я предположим, что g инициализируется?
  • какой тип объекта должен Gadget быть для этого кода для компиляции?
  • какая концепция работает на этой линии:Gadget g {n};? т. е. Что такое фигурные скобки после объявления?
  • (возможно, слишком широкий, но) почему компилятор не распознает фигурные скобки как допустимый синтаксис?

1 ответов


правильно ли я предполагаю, что экземпляр g создается?

Да, вы правы.

какой тип объекта должен Gadget быть для компиляции этого кода?

любой тип, который может быть инициализирован из int. Например, если ваш Gadget класс имеет конструктор принимает int, или взять что-то, что может быть инициализирован с int, это заставляет код компилироваться.

какая концепция работает на этой линии:Gadget g {n};? т. е. Что такое фигурные скобки после объявления?

это единый синтаксис инициализации. Это устраняет некоторую неприятную проблему с обозначением скобок, которая заставит компилятор C++ анализировать следующее как объявление функции (а не как инициализацию объекта):

struct Widget { /* ... */ };
struct Gadget { Gadget(Widget const&) { /* ... */ } /* ... */ };

Gadget g(Widget()); // This is parsed a FUNCTION DECLARATION

в приведенном выше примере целью программиста могло быть создание объекта g of тип Gadget и инициализируйте его из временного Widget object: однако компилятор будет анализировать это как объявление функции с именем g что возвращает Gadget и принимает в качестве аргумента функцию a (указатель на A), которая не принимает аргументов и возвращает Widget. Это известно как Самый Досадный Разбор проблема.

обратите внимание, что при использовании фигурных скобок вышеуказанная проблема не существует:

Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!

(возможно, слишком широкий, но) почему компилятор не распознает фигурные скобки как допустимый синтаксис?

это скорее всего потому, что вы не используете с++11-совместимый компилятор. Вы должны использовать один, и использовать -std=c++11 или -std=c++0x флаг компиляции для включения поддержки C++11.