C ++ Lite Вопрос 10.19. Функция вместо переменной decl - PullRequest
1 голос
/ 01 августа 2009

У меня была такая проблема со мной в прошлом http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.19

Мой вопрос, когда пишу

Foo x(Bar());

Почему это "объявление функции, не являющейся членом, которая возвращает объект Bar"? я могу понять это, если я написал

Foo x(Bar);

Но что, по его мнению, означает () в Bar ()?

Ответы [ 3 ]

5 голосов
/ 01 августа 2009

Bar() там означает «функция, которая не принимает аргументов и возвращает Bar». Рассмотрим объявление такой функции:

Bar GetBar();

если вы удалите имя функции из этого, то останется описать тип функции. Некоторые примеры его использования приведены в аргументах шаблона; например Вы можете написать это:

std::function<int(float)> f1;
std::function<Bar()> f2;

Надеюсь, это объясняет синтаксис в целом. Теперь, что это значит в данном конкретном случае. Когда тип функции используется в качестве типа аргумента функции, он автоматически заменяется типом указателя на функцию. Таким образом, эквивалентное (но более четкое) объявление будет:

Foo x(Bar(*)());
3 голосов
/ 01 августа 2009

Рассмотрим следующий более простой пример:

void fn1(int a)
{
}

fn1 - это функция, которая принимает один параметр типа int.

Теперь взгляните на fn2:

//Same as typing void fn2(int (*b)()) 
void fn2(int b())
{
}

Здесь fn2 не принимает int, но принимает функцию, которая возвращает int.

Теперь, если вы хотите объявить fn1, вы можете напечатать его так:

void fn1(int);//ommit the parameter name

И вы также можете объявить fn2 так:

void fn2(int());

Пример использования:

#include <iostream>

int a()
{
  sd::cout<<"hi"<<std::endl;
  return 0;
}

void fn2(int b())
{
  b();
}

int main(int argc, char **argv)
{
  fn1(3);
  fn2(a);
}

Вывод будет:

привет

Теперь есть еще одна тема, которую нужно понять ... Вы можете переслать объявление функций с областью действия.

a.cpp:

void a()
{
  void c();
  c();
}

//void b()
//{
//   c();//<--- undeclared identifier
//}

int main(int argc, char**argv)
{
   a();
   return 0;
}

c.cpp

#include <iostream>

void c()
{
   std::cout<<"called me"<<std::endl;
}

g ++ a.cpp c.cpp ./a.out

Вывод будет:

Позвонил мне

И связывая все это вместе. Если вы сделаете это:

int main(int argc, char**argv)
{
  int b();

  return 0;
}

Вы можете объявить функцию b (), которая возвращает тип int и не принимает параметров

Если бы вы сделали b = 3; тогда вы получите ошибку компиляции, поскольку вы не можете присвоить значение объявленной вперед функции.

И как только вы прочитаете все, станет ясно:

Foo x(Bar());

Вы ожидаете объявить функцию x, которая возвращает тип Foo и принимает параметр для функции, которая возвращает тип Bar.

0 голосов
/ 01 августа 2009

К сожалению, похоже, что он не в сети, но книга Скотта Мейерса, Effective STL , содержит хорошее подробное объяснение того, что происходит в вашем примере в Пункт 6: Будьте бдительны для самого неприятного синтаксического анализа C ++ .

С другой стороны, книга стоит того, кто серьезно относится к C ++.

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