C++ Lambda 本地变量捕获错误

huangapple go评论118阅读模式
英文:

C++ Lambda Local Variable Capturing Error

问题

我正在尝试使用lambda表达式使inorderTraversal函数可重用,但在尝试捕获printStandartDeviation函数的本地参数时出现以下错误:无法从'lambda at [...]/AVLTree.cpp:[...]'转换为'void (*)(AVLTree::TreeNode *)&'。

它会在我将本地变量设为静态或全局变量时修复,但实际上我不想这样做。

我也愿意接受替代方案,而不是使用lambda。

如果您能帮助我,我将不胜感激。

英文:

I am trying to use a lambda expression to make inorderTraversal function reusable, and I am having the following error while trying to capture the local parameters of printStandartDeviation function: No viable conversion from '(lambda at [...]/AVLTree.cpp:[...])' to 'void (*)(AVLTree::TreeNode *)'.

  1. void AVLTree::printStandartDeviation() {
  2. int totalWordCount = 0, totalWordFrequencies = 0;
  3. inorderTraversal(root, [&totalWordCount, &totalWordFrequencies](TreeNode *tNode) {
  4. totalWordCount++;
  5. totalWordFrequencies += tNode->frequency;
  6. });
  7. }
  8. void AVLTree::inorderTraversal(TreeNode *tNode, void (*visit)(TreeNode *)) {
  9. if (tNode == nullptr) {
  10. return;
  11. } else {
  12. inorderTraversal(tNode->left, visit);
  13. visit(tNode);
  14. inorderTraversal(tNode->right, visit);
  15. }
  16. }

It fixes if I make my local variables static or make them global, but I do not want to do either actually.

I am also open to alternative solutions as well instead of using lambda.

I would be grateful if you can help.

答案1

得分: 2

一个Lambda表达式不是一个函数指针。一个非捕获Lambda具有转换为函数指针的能力,但带有捕获的Lambda不具备这种能力。这在某种程度上类似于自由函数指针和成员函数指针之间的差异,仅有成员函数指针本身几乎没有用处。你需要一个对象来调用成员函数。在这里,你还需要数据,也就是捕获的变量,来调用Lambda表达式,它不仅仅是一个函数。

你不需要一个函数指针。只需将Lambda表达式原样传递,由于Lambda的类型没有名称,可以将这个方法设为模板以使其工作:

  1. template <typename F>
  2. void AVLTree::inorderTraversal(TreeNode *tNode, F&& visit) {
  3. // 所有内容相同
  4. }
英文:

A lambda is not a function pointer. A non-capturing lambda has a conversion to function pointer but one with captures not. It is somewhat similar to the difference between a pointer to free function and pointer to member function where the pointer to member function alone is of little use. You need an object to call a member function. Here you also need the data, the captured variables, to call the lambda, its not just a function.

You do not need a function pointer. Simply pass the lambda as it is, and because the lambdas type has no name, make the method a template to make this work:

  1. template &lt;typename F&gt;
  2. void AVLTree::inorderTraversal(TreeNode *tNode, F&amp;&amp; visit) {
  3. // all the same
  4. }

huangapple
  • 本文由 发表于 2023年8月4日 01:06:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830228.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定