以下代码会产生分段错误,我不知道原因:
myTree<int> tree;
tree.insert(10); // not important
std::vector<int> v = tree.toVector(); // Segmentation fault
这是myTree代码(缩小,不可编译,只是足以理解它的含义):
template<class T> struct node {
T key;
node *left;
node *right;
int count;
node(const T &k=T(), node *l=0, node *r=0) {
key = k;
left = l;
right = r;
count = 1;
}
};
template<class T> class myTree {
public:
myTree() {
root = 0;
}
void traverseInOrder(void (*visitFunc)(node<T>* n)) {
traverseInOrder(visitFunc, root);
}
std::vector<T> toVector() {
std::vector<T> v;
traverseInOrder([&](node<T>* n) {
v.insert(v.end(), n->count, n->key);
});
return v;
}
private:
void traverseInOrder(void (*visitFunc)(node<T> *n), node<T> *n) {
if (n == 0) {
return;
} else {
if (n->left != 0) {
traverseInOrder(visitFunc, n->left);
}
(*visitFunc)(n);
traverseInOrder(visitFunc, n->right);
}
}
node<T> *root;
};
分段错误发生在这一行:
v.insert(v.end(), n->count, n->key);
NetBeans变量窗口说v是OUT_OF_SCOPE。
问题:我是否正确使用lambda?
注意:我使用的是g ++(GCC)4.7.2(Cygwin)。
答案 0 :(得分:5)
正如@Arkadiy在评论中所提到的,有状态的lambda不会衰减为函数指针。解决方法是将traverseInOrder
编写为一个采用可调用对象的模板
template<class Func>
void traverseInOrder(Func visitFunc)) {
traverseInOrder(visitFunc, root);
}
或者,您可能更安全,并为其提供一个签名,该签名会std::function
返回void
并获取node<T>*
void traverseInOrder(std::function<void(node<T>*)> visitFunc)) {
traverseInOrder(visitFunc, root);
}