我创建了一个具有遍历功能的字典,该字典对遍历的每个节点进行回调。
签名:
void traverse(void visit(ItemType&)) const;
实施:
template < class KeyType, class ItemType>
void HashedDictionary< KeyType, ItemType>::traverse(void visit(ItemType&)) const {
HashedEntry<KeyType, ItemType> *currPtr;
for (int i = 0; i < hashTableSize; i++) {
currPtr = hashTable[i];
while (currPtr != nullptr) {
ItemType currItem = currPtr->getItem();
visit(currItem);
currPtr = currPtr->getNext();
}
}
}
当前我正在使用此回调
void visit(Person& p) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
d->traverse(visit);
但是,我想为month添加一个参数,其中仅当month是某个值时才显示名称。
如何将月份传递给此功能?可以起到以下作用的
d->traverse(visit(4));
第4个月...
答案 0 :(得分:2)
如何将月份传递给此功能?
目前不能。您遍历的原型是:
void traverse(void visit(ItemType&)) const;
如果它看起来更像:
template<typename TraverseFunc>
void traverse(TraverseFunc& visit) const;
然后,您可以将函数替换为函数对象,即
struct MyVisitor {
int month;
MyVisitor(int month) : month(month) {}
// overload () operator
void operator () (ItemType& item) {
// do thing to item
}
};
然后您就可以做到:
d->traverse(MyVisitor(4));
答案 1 :(得分:1)
您可以声明traverse()
方法以接受访问者的任何可调用类型,例如:
template < class KeyType, class ItemType, class VisitorType >
void HashedDictionary< KeyType, ItemType>::traverse(VisitorType visit) const {
HashedEntry<KeyType, ItemType> *currPtr;
for (int i = 0; i < hashTableSize; i++) {
currPtr = hashTable[i];
while (currPtr) {
ItemType currItem = currPtr->getItem();
visit(currItem);
currPtr = currPtr->getNext();
}
}
}
然后您可以传递函子或函数,例如:
struct visit {
int month;
visit (int mon) : month(mon) {}
void operator()(Person& p) {
if (p.getMonth() == month) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
}
};
d->traverse(visit(4));
void visitIfApril(Person& p) {
if (p.getMonth() == 4) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
}
d->traverse(visitIfApril);
template<const int month>
void visitIf(Person& p) {
if (p.getMonth() == month) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
}
d->traverse(visitIf<4>);
在C ++ 11和更高版本中,您也可以传入lambda代替:
d->traverse(
[](Person& p) {
if (p.getMonth() == 4) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
}
);
另一种选择是给traverse()
一个附加的用户定义参数,然后传递给回调函数,例如:
template < class KeyType, class ItemType, class UserType >
void HashedDictionary< KeyType, ItemType>::traverse(void visit(ItemType&), UserType user) const {
HashedEntry<KeyType, ItemType> *currPtr;
for (int i = 0; i < hashTableSize; i++) {
currPtr = hashTable[i];
while (currPtr) {
ItemType currItem = currPtr->getItem();
visit(currItem, user);
currPtr = currPtr->getNext();
}
}
}
void visit(Person& p, int month) {
if p.getMonth() == month) {
cout << p.getName() << ": " << p.getMonth() << "/" << p.getDay() << "/" << p.getYear() << endl;
}
}
d->traverse(visit, 4);
答案 2 :(得分:0)
您需要传递函数指针以及作为参数传递的函数所需的所有参数。因此,在您的情况下,应将month
作为参数传递给traverse
函数。
签名:
void traverse(void visit(ItemType&), int month) const;
visit()
函数应具有参数month:
void visit(Person& p, int month);
现在您可以像这样调用遍历函数:
d->traverse(visit, 4);