2013-06-26 36 views
2

下面的代码生成分段错误,我不知道为什么:C++的λ分段故障

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变量WINDO w表示v是OUT_OF_SCOPE。

问题:我正确使用lambda吗?

注意:我正在使用g ++(GCC)4.7.2(Cygwin)。

+3

这是一个关于如何理解您编写的代码以及如何使用调试器的问题? – 2013-06-26 18:09:36

+0

t的价值是什么?另外,尝试插入()调用,并找出'this'的值在那里。与上面定义'v'的栈帧中的'&v'比较。 – Arkadiy

+4

啊 - 这很有趣。根据这个(http://stackoverflow.com/a/2993349/3458)只有无状态lambda可以作为函数指针传递。你的国家不是无国籍的。 – Arkadiy

回答

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); 
} 
+1

或使用std :: function – Arkadiy

+0

非常感谢!对不起,没有提供一个可编辑的例子。 – robert

+0

@Arkadiy tnx,已更新。 – TemplateRex