我试图通过属于模板化print
的{{1}}类将我的inordertraversal
函数作为参数传递。每当我在main中定义这些函数时,程序就可以正常工作,但是每当尝试封装它们时,我都会收到错误消息:
binarySearchTree
这是有效的代码
"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
的声明与上面的声明在 .cpp 中)
binarySearchTree
错误是在void bst::printfunctions(classdatatype& x)
{
tree.inorderTraversal(print(classdatatype & x)); //error here
}
void bst::print(classdatatype& x)
{
cout << x << " ";
}
中引起的,我已经尝试了许多不同的方法,但是对我来说,这是正确的声明。因此我不知道为什么它不起作用。
任何建议将不胜感激。
编辑:print
是一个函数指针,用于打印存储在二进制搜索树中的print
的详细信息。
EDIT2 :最小的可复制示例。
数据类型保持不变,与上面的示例不同。这是我可以做到的最基本的操作,最终我得到了另一个我无法解决的错误,但就本示例而言,这无关紧要,应该忽略。
classdatatype
已包含在内,但数量很少,可能无法达到目的,但问题仍然不在这里。
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
答案 0 :(得分:3)
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>
。在那种情况下,仅传递 member-function 是不够的,此外还应传递将调用print
函数的类的实例 >。
通过捕获bst
类的实例并传递给{{1}的inorderTraversal()
, Lambda 函数可以很方便地简化此过程}类。
这意味着在binarySearchTree
内提供:
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
此处正在编译代码:https://godbolt.org/z/jhCnPs
PS :另一个错误是来自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
}
类的operator<<
,您错过了返回windlogtype
的引用的错误。
说实话,通过用std::ostream
代替windlogtype
并在声明旁边显示成员函数的定义,您可以制作出更简单的最小代码。这将使代码易于阅读。