C++ 中奇怪的函数声明和 lambdas
Posted
技术标签:
【中文标题】C++ 中奇怪的函数声明和 lambdas【英文标题】:Weird function declaration and lambdas in C++ 【发布时间】:2020-04-14 15:43:29 【问题描述】:所以我正在浏览一些笔记,但我被一些奇怪的声明弄糊涂了。 在下面的代码段中,您可以看到下面的代码块有一个分配给自动变量的函数
#include<iostream>
using namespace std;
void Hi(int a)
cout << "Hi" << a << endl;
int main()
auto Print = Hi;
Print(5);
但是函数(这里的'Hi')没有括号()并且它仍然有效..那么它是如何工作的? 更让我心动的是它的类型是什么?最后,当我们调用该变量时,它会打印“Hi5”。
我对这部分很好奇,因为这只是我们代码的一个示例部分。 我们需要制作一个 for-each 循环函数的工作示例,以使用这种类型在向量中显示值。
我似乎找不到任何线索,因为我什至不知道类型..但是我们的教授确实提到要更好地使用“lambdas”,我在网上查了一下,但我不清楚这是什么。任何提醒都会非常有帮助。
【问题讨论】:
“我什至不知道类型” - 如果您使用适当的调试器或像 Visual Studio 这样的 IDE,您只需将鼠标悬停在变量名称上即可查看其类型。它看起来像一个函数指针。 请教你的教授。 但是函数(这里的'Hi')没有括号(),它仍然有效 -- 没有括号,它是一个函数指针。这与 lambdas 无关。 帮自己一个忙,写成auto Print = &Hi;
和(*Print)(5);
仅仅因为函数名可以隐式衰减为指针并不意味着你应该这样做。
【参考方案1】:
但是函数(这里的'Hi')没有括号()并且它仍然有效..那么它是如何工作的?
您在这里看到的是一个函数指针,顾名思义,它通常是指向函数的指针。
毕竟,函数只是 CPU 指令,存储在二进制可执行文件中的某个位置,该函数指针指向内存中函数的地址。
我们实际上是在检索那些 CPU 指令的位置,其中使用了引用 (&
),这最终等同于 &Hi
。 (存在隐式转换,因此编写 Hi
就足够了。)
让我更感兴趣的是它的类型是什么?
它的 void(*Print)(int)
类型,一个 void 类型的函数指针,接受一个整数作为参数。第一个带有取消引用 *
的 ()
包含函数的名称,在您的示例中为 Print
。
(它可以是任何东西,取决于你的自动变量的名称。)第二个()
表示传递给函数的参数类型,在你的例子中是一个整数,所以有一个int
。
由于它是一个有效的类型,你也可以使用 typedef 来定义它:
typedef void(*printHiFunction)(int);
printHiFunction Print = Hi;
Print(5);
我们需要制作一个 for-each 循环函数的工作示例,以使用这种类型在向量中显示值。我似乎找不到任何线索,因为我什至不知道类型..但是我们的教授确实提到要更好地使用“lambdas”,我在网上查了一下,但我不清楚它是什么.任何提醒都会非常有帮助。
我不明白您如何仅使用函数指针来实现它(或者当您可以简单地不使用它时有什么用处)。 否则,您的教授可能希望您绝对使用 lambda。 它只是一个匿名临时函数,可以在必要时调用(并像丢弃函数一样相应地丢弃),也可以作为参数传递给函数。 更多信息,您可以参考here。
对于基于范围的循环,您至少需要传入一个向量,您可以将其声明为 const
并像左值一样通过引用传递它,并将函数指针作为第二个参数传递给您的对于每个循环功能。
然后,您可以使用 lambda 代替带有 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
【讨论】:
感谢您的详尽回答。lambda 中的 '[ ]' 是什么意思? @LightYagami[]
位用于捕获变量。在这种情况下,捕获列表为空。
@LightYagami 这是捕获子句,用于指定如何将变量包含在 lambda 表达式中。例如:[=]
属于可以访问所有局部变量(每个变量的副本)的 lambda,[&]
属于可以通过引用访问的 lambda,等等。您还可以包含特定变量,例如您有一个int a
变量,您可以通过在捕获列表[&a]
中提及它来通过引用特别指定它【参考方案2】:
你在这里看到的是一个函数指针。函数指针,顾名思义,指向返回给定类型并接受给定参数列表的函数。 在您的示例中,Print 变量是一个指向函数的指针,该函数返回 void 并接受一个 int 类型的参数。 我建议您阅读this article 中有关函数指针的部分,并按照 Anirban166 的建议,使用带有调试器的 IDE。
【讨论】:
以上是关于C++ 中奇怪的函数声明和 lambdas的主要内容,如果未能解决你的问题,请参考以下文章