首页 > 解决方案 > 为什么在重载的 ostream 运算符中引用 lambda 中的向量会导致错误?

问题描述

在我的矩阵实现中,我使用向量向量作为私有成员。我重载了ostream运算符,因此可以打印矩阵中的所有值。在下面的代码中,我首先使用for_each迭代矩阵的“行”。在 lambda 中,我在这一行的末尾指定了一个参数(矩阵“列”)作为对向量的引用:

std::for_each(p_matrix.m_vector_of_vectors.begin(), p_matrix.m_vector_of_vectors.end(), [& p_out] (std::vector<int> & el)

这会导致错误。这是完整的代码:

#include <iostream>
#include <vector>
#include <algorithm>

class Matrix{
  public:
    Matrix()
    {
       m_vector_of_vectors = {{1,2,3},{4,5,6},{7,8,9}};
    }
    friend std::ostream & operator << (std::ostream & p_out, const Matrix & p_matrix)
    {
        std::for_each(p_matrix.m_vector_of_vectors.begin(), p_matrix.m_vector_of_vectors.end(), [& p_out] (std::vector<int> & el)
        {
            std::for_each(el.begin(), el.end(), [& p_out] (int & el2)
            {
                p_out << el2 << " "; 
            });
            p_out << std::endl;
        });
        return p_out;
    }
  private:
    std::vector<std::vector<int>> m_vector_of_vectors;
};

int main()
{
    Matrix l_matrix;
    std::cout << l_matrix;
    return 0;
}

这是完整的错误打印:

In file included from /usr/include/c++/5/algorithm:62:0,
                 from main.cpp:11:
/usr/include/c++/5/bits/stl_algo.h:

In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<const std::vector<int>*, std::vector<std::vector<int> > >; _Funct = operator<<(std::ostream&, Matrix)::<lambda(std::vector<int>&)>]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',29)">main.cpp:29:10</span>:   required from here

/usr/include/c++/5/bits/stl_algo.h:3767:5: error: no match for call to ‘(operator<<(std::ostream&, Matrix)::&)>) (const std::vector&)’
 __f(*__first);

main.cpp:22:129: note: candidate: operator<<(std::ostream&, Matrix)::&)> 
         std::for_each(p_matrix.m_vector_of_vectors.begin(), p_matrix.m_vector_of_vectors.end(), [& p_out] (std::vector<int> & el)

没有参考一切正常:

std::for_each(p_matrix.m_vector_of_vectors.begin(), p_matrix.m_vector_of_vectors.end(), [& p_out] (std::vector<int> el)

有人可以解释为什么这个单一的参考是至关重要的吗?在第二个(内部)lambda 代码中,有无参考均可。重载运算符中的 p_matrix 参数也是如此。我尝试循环遍历作为正常变量的向量向量:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<std::vector<int>> a = {{1,2,3},{4,5,6},{7,8,9}};
    std::for_each(a.begin(), a.end(), [] (std::vector<int> & el)
    {
       std::for_each(el.begin(), el.end(), [] (int & el2)
       {
          std::cout << el2; 
       });
    });

    return 0;
}

这工作正常,所以我假设这个错误与重载运算符有关。感谢帮助。

标签: c++

解决方案


Matrix通过 const-ref 获取(这是正确的),因此,您也必须通过 const-ref 获取向量(或通过值,这涉及副本):

std::for_each(
  p_matrix.m_vector_of_vectors.begin(),
  p_matrix.m_vector_of_vectors.end(),
  [& p_out] (***const*** std::vector<int> & el)
...

(您的第二个示例有效,因为a它是非常量,因此 lambda 可以采用非常量引用)


推荐阅读