如何在类中将函数作为参数传递?
Posted
技术标签:
【中文标题】如何在类中将函数作为参数传递?【英文标题】:How to pass functions as parameters within a class? 【发布时间】:2019-06-02 14:19:14 【问题描述】:我试图通过我的inordertraversal
类将我的print
函数作为参数传递,该类属于模板化binarySearchTree
。每当我在 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))
如果需要,我可以显示其余代码,但这一切都很好
一旦我将这些函数移到我的类中,它看起来像这样
(print
和 binarySearchTree
的声明在 .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()
包含在内,但很小,可能无法达到其目的,但问题不在于这里。
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
【问题讨论】:
有什么理由不使用std::function
作为参数类型?
我对 c++ 很陌生,我不确定 std::function 是什么或如何使用它。
en.cppreference.com/w/cpp/utility/functional/function
当你把这个函数移到你的类中时,你把它改成static
了吗?如果您提供minimal reproducible example 会更好。
只是为了澄清:你是否试图将 print
从 bst
类传递给 inorderTraversal
的 binarySearchTree<elemType>
类?
【参考方案1】:
void bst::print(classdatatype& x) // is a member function
和
void print(classdatatype& x); // is a free function.
因此function pointers to hold them 也会有所不同。
OP 在 cmets 中提到,他/她想将成员函数 print()
从 bst
类传递给 binarySearchTree<elemType>
类的成员函数inorderTraversal()
。在那种情况下传递成员函数是不够的,此外还应该传递print
函数将被调用到的类的实例。
Lambda 函数可以通过捕获bst
类的实例并传递给binarySearchTree
类的inorderTraversal()
来方便地简化此操作。
也就是说,在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:另一个错误来自windlogtype
类的operator<<
,您错过了返回std::ostream
的引用。
老实说,您可以通过将windlogtype
替换为int
并在声明旁边显示成员函数的定义来制作更简单的最小代码。这将使代码易于阅读。
【讨论】:
以上是关于如何在类中将函数作为参数传递?的主要内容,如果未能解决你的问题,请参考以下文章