вызов конструктора можно рассматривать как объявление функции? - PullRequest
4 голосов
/ 18 января 2012

Следующие несколько строк, которые я собираюсь написать, взяты из книги «Стандартная библиотека C ++ - руководство и справочник».

Инициализация с использованием стандартного ввода:

//read all integer elements of the deque from standard input
std::deque<int> c((std::istream_iterator<int>(std::cin)),
(std::istream_iterator<int>()));

Не забывайте дополнительные скобки вокруг аргументов инициализатора здесь.В противном случае это выражение делает что-то совсем другое, и вы, вероятно, получите некоторые странные предупреждения или ошибки в следующих утверждениях.Попробуйте написать оператор без лишних скобок:

std::deque<int> c(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>());

В этом случае c объявляет функцию с возвращаемым типом deque.Его первый параметр имеет тип istream_iterator с именем cin, а второй безымянный параметр имеет тип «функция не принимает аргументов, возвращая istream_iterator».Эта конструкция является синтаксически допустимой как объявление или выражение.Таким образом, согласно правилам языка, это рассматривается как декларация.Дополнительные скобки заставляют инициализатор не соответствовать синтаксису объявления.

Я могу понять, почему тот, у которого есть дополнительные скобки, не считается объявлением функции, но я не вижу, что могло бы сделатьодин без объявления функции, хотя?Ведь у него круглые скобки (std::cin), и, насколько я знаю, переменные могут не иметь имен с круглыми скобками?

Я что-то упустил?

Ответы [ 3 ]

5 голосов
/ 18 января 2012

Учебное пособие, которое вы прочитали, неверно.Это:

std::deque<int> c(std::istream_iterator<int>(std::cin), std::istream_iterator<int>());

Не может быть проанализировано как объявление функции , поскольку std::cin не может быть именем параметра .Если вы удалите квалификатор std, хотя:

std::deque<int> c(std::istream_iterator<int>(cin), std::istream_iterator<int>());

, тогда вы получите объявление функции.

[...] иНасколько я знаю, переменные могут не иметь имен с круглыми скобками?

Скобки не являются частью имени.Вы можете просто положить их туда, сколько хотите:

int ((((((a)))))) = 12345; // valid code!
a++; // the variable is named 'a'
3 голосов
/ 18 января 2012

Если оператор может быть проанализирован как прототип функции или объявление переменной с аргументом конструктора, прототип функции имеет преимущество. Это противоречит ожиданиям большинства людей, и поэтому он называется Most Vexing Parse .

1 голос
/ 18 января 2012

Насколько я знаю, переменные могут не иметь имен с круглыми скобками

Это неверное предположение;круглые скобки не являются частью имени переменной, они просто игнорируются (в этом контексте).

Из стандарта C ++ ( [dcl.decl] ):

декларатор:

  • ptr-декларатор
  • noptr-декларатор параметры-и-квалификаторы trailing-return-type

ptr-декларатор:

  • noptr-декларатор
  • ptr-оператор ptr-декларатор

noptr-декларатор:

  • идентификатор декларатораСпецификатор атрибута opt
  • Параметры-спецификаторы noptr-объявлений
  • Объявление-noptr [ выражение-константы opt ] атрибут-спецификатор опция
  • ( ptr-декларатор )

и ( [dcl.fct] ):

параметр-объявление-условие:

  • параметр-объявление-список опция ... opt
  • список объявлений параметров , ...

список объявлений параметров:

  • объявление параметров
  • список объявлений параметров , объявление параметров

объявление параметров:

  • спецификатор атрибута opt декларатор decl-спецификатор-seq
  • спецификатор атрибута opt декларатор decl-specier-seq = выражение-присваивание
  • спецификатор-атрибута opt decl-спецификатор-seq аннотация-декларатор opt
  • атрибут-спецификатор opt decl-спецификатор-seq абстрактный-декларатор opt = выражение-присваивание

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...