Вложенные вызовы конструктора C ++ против объявления функций - PullRequest
2 голосов
/ 04 августа 2011

В чем разница между фрагментами кода с надписью «версия 1» и «версия 2» в следующем разделе кода:

int main() {
  using namespace std;
  typedef istream_iterator<int> input;

  // version 1)
  //vector<int> v(input(cin), input());

  // version 2)
  input endofinput;
  vector<int> v(input(cin), endofinput);
}

Насколько я понимаю, «версия 1» рассматривается как объявление функции,Но я не понимаю, почему и каковы аргументы полученной функции v с типом возврата vector<int>.

Ответы [ 3 ]

4 голосов
/ 04 августа 2011

почему

Поскольку в стандарте более или менее сказано, что все, что может быть интерпретировано как объявление функции, будет в любом контексте не зависимо от того, что.

что за аргументы ...

Вы можете не верить этому, но это правда.input(cin) трактуется как input cin;в этом месте круглые скобки разрешены и просто бессмысленны.Однако input() не считается объявлением параметра типа input без имени;вместо этого это параметр типа input(*)(), то есть указатель на функцию, не принимающую аргументов и возвращающую input.Часть (*), по-видимому, не нужна для объявления типа.Я думаю, по той же причине, что & является необязательным, когда вы используете имя функции для инициализации указателя функции ...

Другой способ обойти это, используя тот факт, что мы объявляемв любом случае значения отдельно, чтобы оправдать пропуск typedef:

istream_iterator<int> start(cin), end;
vector<int> v(start, end);

Другим способом является добавление скобок способом, который не разрешен для объявлений функций:

vector<int> v((input(cin)), input());

Для получения дополнительной информации,Google "c ++ самый неприятный анализ".

2 голосов
/ 04 августа 2011

Это называется самый неприятный анализ :

Этот фрагмент:

  input()

может быть двусмысленен как

  1. определение переменной для ввода класса переменной, принимая анонимный экземпляр ввода класса или
  2. объявление функции для функции, которая возвращает объект типа input и принимает единственный (неназванный) аргумент, который является функцией, возвращающей тип input (и не требующей ввода).

Большинство программистов ожидают первого, но стандарт C ++ требует, чтобы оно интерпретировалось как второе.

1 голос
/ 04 августа 2011
vector<int> v(input(cin), input());

Ну, аргументы этого объявления функции таковы:

  • input(cin) - это объект
  • input (*)() - указатель на функцию, возвращающую input и не имеющую аргумента.
...