Reputation: 89
I am trying to pass my print
function as a paramater through my inordertraversal
class which belongs to a templated binarySearchTree
. whenever I define these functions within main the program works fine but whenever i try to encapsulate them I get a error:
"expected primary-expression before '&' token"
This is the code that works
void print(classdatatype& x);
int main()
{
binarySearchTree<classdatatype> tree;
tree.inorderTraversal(print);
return 0;
}
void print(classdatatype& x) { cout << x << " "; }
The declaration of my inordertraveral
templated class is
template <class elemType>
void binarySearchTree<elemType>::inorderTraversal(void (*visit)(elemType& item))
I can show the rest of the code if needed but this all works just fine
Once I move these functions into my class it looks like this
(the declarations for print
and the binarySearchTree
are in the .cpp same as they are declared above)
void bst::printfunctions(classdatatype& x)
{
tree.inorderTraversal(print(classdatatype & x)); //error here
}
void bst::print(classdatatype& x)
{
cout << x << " ";
}
The error is to do within the brackets of print
, I have tried many different things but to me this is the correct declaration; therefore I don't know why it's not working.
Any advice would be greatly appreciated.
EDIT: print
is a function pointer to print the details of classdatatype
which is stored inside a binary search tree.
EDIT2: minimal reproducible example.
Data types are as they are and not like in the above example. This is as basic as I could make this and I ended up getting another error which I couldn't resolve but for the purpose of this example it doesn't matter and should be ignored.
main()
is included but is minimal and may not serve its purpose but the problem doesn't lie here anyway.
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;
}
class 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
class 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);
}
}
class 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
}
Upvotes: 2
Views: 141
Reputation: 32722
The
void bst::print(classdatatype& x) // is a member function
and
void print(classdatatype& x); // is a free function.
Hence the function pointers to hold them will be also different.
The OP has mentioned in the comments, that he/she wants to pass the member function print()
from bst
class to member functioninorderTraversal()
of binarySearchTree<elemType>
class. In that case passing the member-function is not sufficient, in addition to that the instance of the class to which the print
function will be called also should be passed.
The Lambda function can come in handy to simplify this by capturing the instance of bst
class and pass to the inorderTraversal()
of the binarySearchTree
class.
That means, inside template <class elemType> class binarySearchTree
provide:
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));
}
}
Inside the bst
class
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
}
Here is compiling code: https://godbolt.org/z/jhCnPs
PS: The other error was from operator<<
of windlogtype
class where you missed to return the reference of std::ostream
.
To be honest, you could have made a further simpler minimal code, by replacing windlogtype
with int
and showing the defenitions of the member function next to the declaration. That would make the code to read easily.
Upvotes: 4