Странное объявление функции и лямбда в C ++ - PullRequest
3 голосов
/ 14 апреля 2020

Итак, я просматривал некоторые заметки, и меня смутили странные заявления. В приведенном ниже фрагменте кода вы можете видеть, что в приведенном ниже фрагменте кода есть функция, которая назначается автоматической переменной

#include<iostream>
using namespace std;
void Hi(int a)
{  
    cout << "Hi" << a << endl;
}

int main()
{
    auto Print = Hi;
    Print(5);
}

Но функция (здесь «Hi») не имеет скобок (), и она по-прежнему работает .. так как это работает? Что меня больше тянет, так это каков его тип? И в конце, когда мы вызываем эту переменную, она печатает «Hi5».

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

Кажется, я не могу найти на нем никаких следов, потому что даже не знаю типа ... но наш профессор упомянул об использовании «лямбды» к лучшему, что я искал в net, но я не мог получить четкое представление о том, что это такое. Любая поддержка была бы очень полезна.

Ответы [ 2 ]

6 голосов
/ 14 апреля 2020

Но у функции (здесь «Привет») нет скобок (), и она все еще работает ... так как она работает?

Что вы наблюдаете здесь, это указатель на функцию , который, как следует из названия, является указателем на функцию. Функции, в конце концов, просто инструкции процессора, хранятся где-то в вашем двоичном исполняемом файле, и этот указатель на функцию указывает на адрес функции в памяти. На самом деле мы извлекаем местоположение этих инструкций процессора, где используется ссылка (&), и это в итоге эквивалентно &Hi. (существует неявное преобразование, и поэтому достаточно написать Hi)

Что меня больше привлекает, так это какой у него тип?

Его типа void(*Print)(int), указатель на функцию пустого типа, принимающий целое число в качестве аргумента. Первый () с разыменовывающим * содержит имя функции, которое в вашем примере Print. (Это может быть что угодно, в зависимости от имени вашей автоматической переменной) Второй () обозначает тип аргумента (ов), передаваемых функции, который в вашем случае является целым числом, поэтому есть int.
Поскольку он является допустимым типом, вы также можете использовать typedef для его определения:

typedef void(*printHiFunction)(int);

  printHiFunction Print = Hi;
  Print(5);

Нам нужно было создать рабочий пример функции для каждого l oop для отображения значения в векторе, используя такой тип. Кажется, я не могу найти какой-то пример, потому что даже не знаю, какой тип… но наш профессор упоминал, что я использую «лямбды» к лучшему, что я нашел в net, но я не мог понять, что именно это. Любая голова была бы очень полезна.

Я не понимаю, как вы могли бы реализовать это, используя только указатель на функцию (или какая польза, когда вы можете просто обойтись без него). В противном случае ваш профессор, вероятно, захочет, чтобы вы наиболее определенно использовали лямбду. Это просто анонимная временная функция, которую можно вызывать при необходимости (и, соответственно, отбрасывать, как одноразовую функцию), а также передавать в качестве аргумента функции. Для получения дополнительной информации вы можете сослаться здесь .


Для вашего l-1045 * на основе диапазона вам нужно будет передать как минимум вектор, который вы можете объявить как быть const и передавать его по ссылке, как lvalues, и указывать указатель функции в качестве второго аргумента для каждой функции l oop. Затем вы можете использовать лямбду вместо указателя на функцию с аргументом int, чтобы просто напечатать это целое число при вызове этого в main():

void ForEach(const std::vector<int>& values, void(*functionPointer)(int))
{
   for (int value : values)
     functionPointer(value);
}
int main()
{
  std::vector<int> values = {1, 2, 3, 4, 5};
  ForEach(values, [](int value)
  { std::cout << value << " "; });
}

Вывод: 1 2 3 4 5

0 голосов
/ 14 апреля 2020

Здесь вы видите указатель на функцию. Указатели на функции, как следует из названия, указывают на функцию, возвращающую данный тип и принимающую данный список аргументов. В вашем примере переменная Print является указателем на функцию, которая возвращает void и принимает один параметр типа int. Я предлагаю вам прочитать раздел об указателях функций в этой статье и, как предложено в Anirban166, использовать IDE с отладчиком.

...