为什么在重载的ostream运算符中引用lambda中的vector会导致错误?

火箭球

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

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;
}

并且工作正常,因此我假设此错误与重载运算符有关。感谢帮助。

内森·奥利弗

friend std::ostream & operator << (std::ostream & p_out, const Matrix & p_matrix)

p_matrixconst也就是说p_matrix.m_vector_of_vectorsconst这意味着p_matrix.m_vector_of_vectors.begin()返回a const_iterator,这意味着传递给lambda的元素是const由于您的lambda采用非const引用,因此不兼容。它将剥离const元素的,这是不允许的。更改lambda以采用const引用,例如

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> const & el) // <- const here
    {
        std::for_each(el.begin(), el.end(), [& p_out] (int const & el2) //<- const here
        {
            p_out << el2 << " "; 
        });
        p_out << std::endl;
    });
    return p_out;
}

然后代码将编译。在第二个示例中,您不需要它,因为a不是,const因此它的迭代器并不const意味着它传递给lambda的元素不是const

我还想指出,基于范围的for循环会使代码更加紧凑。您可以更改operator <<

friend std::ostream & operator << (std::ostream & p_out, const Matrix & p_matrix)
{
    for (auto const& row : p_matrix.m_vector_of_vectors)
    {
        for (auto const& e : row)
            p_out << e << " ";
        p_out << "\n";
    }
    return p_out;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在运算符重载中需要引用?

另一个结构中结构的运算符重载会导致错误

为什么在重载>>和<<运算符时需要返回对istream / ostream的引用?

为什么在带有多个参数的重载运算符+中传递const引用

运算符重载中的引用

为什么SceneKit中没有运算符重载?

在什么情况下忽略useReducer中的传播运算符会导致错误?

重载 ostream 运算符以在文件中写入矩阵

在 C++ 中重载流提取运算符 (>>) 的运算符会导致无限递归流提取

为什么对重载运算符'<<'的异常说明符不适用于任何std :: ostream对象,但对库中定义的异常符无效?

预增量运算符和解引用运算符导致分段错误,似乎无法理解为什么

重载ostream运算符会产生编译错误

为什么<iostream>运算符<<选择明显错误的重载?

在ostream'<<'-运算符重载中使用std :: endl以及带有变体成员的可变模板类会导致编译器错误

C ++中的“未定义引用”运算符重载

为什么插入/提取运算符的重载函数需要ostream / istream参数?

什么是git中的lambda(^)运算符

为什么称为运算符重载?

为什么D中的char []数组没有引发Result类型的[]运算符重载?

为什么在Swift所属类型中未声明运算符重载?

为什么在python中重载数学运算符取决于它的使用顺序?

为什么__getattr__能够处理python 2.x中的内置运算符重载?

在C ++中重载运算符时,为什么T *优于bool?

为什么MSVC中==枚举的运算符重载不明确

在枚举上重载<<运算符会导致运行时错误

在运算符重载中按值传递错误

C ++模板类中的错误重载()运算符

通过继承的运算符重载会导致歧义

为什么重载的移动赋值运算符返回左值引用而不是右值引用?