编译器给出lambda函数强制转换错误

Ton*_*ony 1 c++ templates c++11

首先,定义一个树节点,其中“ BFSTraversal呼吸优先”搜索ReconstructBFS是根据“宽度优先”搜索序列构造一棵树。

template<typename T>
struct TreeNode
{
    T val;
    TreeNode *left;
    TreeNode *right;

    explicit TreeNode(T x) : val(x), left(nullptr), right(nullptr)
    {}

    static void BFSTraversal(TreeNode *node, void visit(T));

    static TreeNode<T> *ReconstructBFS(vector<T> &seq);
};
Run Code Online (Sandbox Code Playgroud)

然后重载<<运算符,这将导致我不理解的编译器错误我的lambda函数有问题吗?

template<typename T>

ostream &operator<<(ostream &os, TreeNode<T> *node)
{
    void (*visit)(T) = [&os](T v) -> void
    { os << v << ','; };

    // compiler error
    // cannot convert 'operator<<(std::ostream&, TreeNode<T>*) 
    // [with T = int; std::ostream = std::basic_ostream<char>]::<lambda(int)>' to 'void (*)(int)' in initialization
    TreeNode<T>::BFSTraversal(node, visit);

    return os;
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我打算实现以下代码。

auto bfs_seq = vector<int>{1,0,2,3}; // 0 represents `null`
TreeNode* root = ReconstructBFS(bfs_seq);
cout << root;
Run Code Online (Sandbox Code Playgroud)

您可以跳过此步骤。我不确定,但是我认为这与我的问题没有直接关系。

执行BFSTraversal

static TreeNode<T> *ReconstructBFS(vector<T> &seq)
{
    auto seq_size = seq.size();
    if (seq_size == 0) return {};
    auto root = new TreeNode<T>(seq[0]);

    queue<TreeNode<T> *> q;
    q.push(root);
    auto level_len = 1, i = 1;
    auto next_level_len = 0;
    auto null_val = T();

    while (!q.empty())
    {
        for (auto j = 0; j < level_len; ++j)
        {
            auto cur_parent = q.front();
            q.pop();

            auto v = seq[i++];
            if (v == null_val) cur_parent->left = nullptr;
            else
            {
                cur_parent->left = new TreeNode(v);
                ++next_level_len;
            }

            v = seq[i++];
            if (v == null_val) cur_parent->right = nullptr;
            else
            {
                cur_parent->right = new TreeNode(v);
                ++next_level_len;
            }
        }

        level_len = next_level_len;
        next_level_len = 0;
    }

    return root;
}
Run Code Online (Sandbox Code Playgroud)

R S*_*ahu 5

仅当未捕获时才能将lambda函数分配给函数指针。如果捕获,则无法将其分配给函数指针。

有关更多信息,请参见将捕获lambda作为函数指针传递

使用std::function代替。

// Not this.
// void (*visit)(T) = [&os](T v) -> void { ... }

std::function<void(T)> visit = [&os](T v) -> void { ... }
Run Code Online (Sandbox Code Playgroud)

当然,这也需要您更改功能BFSTraversal。它应该期望一个std::function而不是一个函数指针。