gpt4 book ai didi

c++ - 如何在类中将函数作为参数传递?

转载 作者:太空狗 更新时间:2023-10-29 20:50:07 27 4
gpt4 key购买 nike

我正在尝试通过属于模板化 binarySearchTreeinordertraversal 类将我的 print 函数作为参数传递。每当我在 main 中定义这些函数时,程序都能正常工作,但每当我尝试封装它们时,我都会收到错误消息:

"expected primary-expression before '&' token"

这是有效的代码

void print(classdatatype& x); 
int main()
{
binarySearchTree<classdatatype> tree;
tree.inorderTraversal(print);
return 0;
}

void print(classdatatype& x) { cout << x << " "; }

我的inordertraveral 模板类的声明是

template <class elemType>
void binarySearchTree<elemType>::inorderTraversal(void (*visit)(elemType& item))

如果需要,我可以展示其余的代码,但这一切都很好

一旦我将这些函数移动到我的类中,它看起来像这样(printbinarySearchTree 的声明在 .cpp 中,与上面声明的相同)

void bst::printfunctions(classdatatype& x)
{
tree.inorderTraversal(print(classdatatype & x)); //error here
}

void bst::print(classdatatype& x)
{
cout << x << " ";
}

错误是在 print 的括号内执行,我尝试了很多不同的方法,但对我来说这是正确的声明;因此我不知道为什么它不起作用。

如有任何建议,我们将不胜感激。


编辑:print 是一个函数指针,用于打印存储在二叉搜索树中的classdatatype 的详细信息。


EDIT2:最小的可重现示例。

数据类型与上例不同。这是我所能做的最基本的,我最终得到了另一个我无法解决的错误,但对于这个例子来说,这无关紧要,应该被忽略。main() 已包括在内,但很小,可能无法达到其目的,但问题并不在于此。

主要()

#include <iostream>
#include "windlogtype.h"
using namespace std;

int main()
{
windlogtype wind;

ifstream infile("data.txt");
//for purose of this data is one integer value
infile >> wind;

//do something
//main purpose is to get input
return 0;
}

windlogtype

#include "windlogtype.h"
windlogtype::windlogtype() { }
windlogtype::windlogtype(int i) { num = i; }
int windlogtype::Getnumber() const { return num; }
void windlogtype::Setnumber(int i) { num = i; }
ostream operator<<(ostream& os, const windlogtype& w)
{
os << w.Getnumber() << '\n';
return os;
}

#ifndef WINDLOGTYPE_H
#define WINDLOGTYPE_H

#include <iostream>
using namespace std;

class windlogtype
{
public:
windlogtype();
windlogtype(int i);
int Getnumber() const;
void Setnumber(int i);
private:
int num;
};
ostream operator<<(ostream& os, const windlogtype& w);

#endif // WINDLOGTYPE_H

binarySearchTree

#include <iostream>
#include <assert.h>
using namespace std;

template <class elemType> struct binaryTreeNode
{
elemType info;
binaryTreeNode<elemType>* llink;
binaryTreeNode<elemType>* rlink;
};

template <class elemType> class binarySearchTree
{
public:
const binarySearchTree<elemType>& operator=(const binarySearchTree<elemType>&);
void inorderTraversal(void (*visit) (elemType&));
binarySearchTree();
~binarySearchTree();
binaryTreeNode<elemType>* root;
private:
void inorder(binaryTreeNode<elemType>* p, void (*visit) (elemType&));
};

template <class elemType> binarySearchTree<elemType>::binarySearchTree() {
root = NULL;
}
template <class elemType> void binarySearchTree<elemType>::inorderTraversal(void (*visit) (elemType& item))
{
inorder(root, *visit);
}
template <class elemType> void binarySearchTree<elemType>::inorder(binaryTreeNode<elemType>* p, void (*visit) (elemType& item))
{
if (p != NULL)
{
inorder(p->llink, *visit);
(*visit)(p->info);
inorder(p->rlink, *visit);
}
}

bst

#ifndef BST_H
#define BST_H
#include "binarySearchTree.h"
#include "windlogtype.h"
using namespace std;

class bst
{
public:
bst();
void InsertTree(windlogtype& newwind);
void printfunctions(windlogtype& x);
binarySearchTree<windlogtype>& GetTree();
void print(windlogtype& x);
private:
binarySearchTree<windlogtype> treeRoot;
};
#endif // BST_H

#include "bst.h"

bst::bst(){/*ctor*/ }
binarySearchTree<windlogtype>& bst::GetTree() { return treeRoot; }
void bst::print(windlogtype& x) { cout << x << " "; }
void bst::printfunctions(windlogtype& x)
{
treeRoot.inorderTraversal(print(windlogtype & x)); // error lies here
}

最佳答案

void bst::print(classdatatype& x) // is a member function

void print(classdatatype& x);    // is a free function.

因此 function pointers to hold them也会不同。


OP 在评论中提到,他/她想传递成员函数 print()来自 bst类到成员函数 inorderTraversal()binarySearchTree<elemType>类(class)。在这种情况下,传递成员函数 是不够的,此外还要传递 print 所指向的类的实例。函数将被调用也应该被传递

Lambda 函数可以派上用场,通过捕获 bst 的实例来简化这一过程。类并传递给 inorderTraversal()binarySearchTree类(class)。

也就是说,在template <class elemType> class binarySearchTree里面提供:

template<typename Callable>
void inorderTraversal(Callable visit)
{
inorder(root, visit); // simply pass visit further
// or avoid coping by warapping std::cref(): i.e. inorder(root, std::cref(visit));
}

template<typename Callable>
void inorder(binaryTreeNode<elemType>* p, Callable visit)
{
if (p != NULL)
{
inorder(p->llink, visit); // or inorder(root, std::cref(visit));
visit(p->info); // call directly with parameter
inorder(p->rlink, visit); // or inorder(root, std::cref(visit));
}
}

bst里面类

void printfunctions(windlogtype& x)
{
// lambda captures the instance by copy
const auto printThisLogType = [this](windlogtype & x)->void { this->print(x); };
treeRoot.inorderTraversal(printThisLogType); // pass the callable lambda
}

这里是编译代码:https://godbolt.org/z/jhCnPs


PS:另一个错误来自 operator<<windlogtype您错过返回 std::ostream 引用的类.

老实说,您可以通过替换 windlogtype 来制作更简单的最小代码。与 int并在声明旁边显示成员函数的定义。这将使代码易于阅读。

关于c++ - 如何在类中将函数作为参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56415885/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com