模板嵌套 class 的构造函数问题(复制构造函数似乎覆盖了其他构造函数)

Issues with constructors for nested class of a template (copy ctor seems to override other ctor)

我有一项家庭作业要做矩阵的模板 class,其中包括一些非常基本和简单的内容。我们还需要为它创建一个前向迭代器class(嵌套迭代器),它以标准方式运行,它应该特别支持复制构造函数。

这里是相关的matrix.h代码:

template<class T>
class Matrix
{
public:
    //nested iterator class
    class iterator
    {

    public:
        typedef iterator self_type;
        typedef T value_type;
        typedef T& reference;
        typedef T* pointer;
        typedef std::vector<T>& vector;

        iterator(Matrix &other, int index) :
            _currIndex(index), _currMatrix(other)
        {

        }

        iterator(iterator& other) :
            _currIndex(other._currIndex), _currMatrix(other._currMatrix)
        {

        }
    private:
        int _currIndex;
        Matrix<T>& _currMatrix;
    }

    //function that creates an iterator for the current matrix
    iterator begin()
    {
        return iterator(*this, 0);
    }

    iterator end()
    {
        return iterator(*this, _data.size());
    }

private:
    unsigned int _rows;
    unsigned int _cols;
    vector<T> _data;
}

Matrix 有多个构造函数,如 copy、empty 等。它们初始化私有成员,仅此而已。迭代器 class 也重载了 ++ 运算符

我面临的问题是使用 g++ 在 Linux 中编译以下代码:

for(auto it = m.begin(); it != m.end(); it++)
{
    cout << *it;
}

在 windows 上,在 Visual Studio 上,代码编译并运行正常,没有任何问题。 在linux上,编译时弹出如下错误:

debug.cpp: In function ‘int main()’:
debug.cpp:63:24: error: no matching function for call to ‘Matrix<int>::iterator::iterator(Matrix<int>::iterator)’
  for (auto it = m.begin(); it != m.end(); it++)
                        ^
debug.cpp:63:24: note: candidates are:
In file included from debug.cpp:11:0:
matrix.h:35:3: note: Matrix<T>::iterator::iterator(Matrix<T>::iterator&) [with T = int]
   iterator(iterator& other) :
   ^
matrix.h:35:3: note:   no known conversion for argument 1 from ‘Matrix<int>::iterator’ to ‘Matrix<int>::iterator&’
matrix.h:29:3: note: Matrix<T>::iterator::iterator(Matrix<T>, int) [with T = int]
   iterator(Matrix other, int index) :
   ^
matrix.h:29:3: note:   candidate expects 2 arguments, 1 provided

如果我注释掉迭代器 class 的复制构造函数,那么代码可以在 Linux(和 windows)上正常编译。如果我保留两个构造函数,则 g++ 会抛出错误。好像复制构造函数覆盖了以前的构造函数,我不知道为什么。

任何人都可以分享一些关于为什么会发生这种情况的见解吗?也许我该如何解决?

您只能将临时文件作为 const&(或按值)传递。 Visual Studio 在这一点上是错误的。复制构造函数的正确签名是:

iterator(const iterator& other) 

复制构造函数中的const很重要,因为只有左值可以绑定到非常量引用,但临时对象是右值,它们不能绑定到非常量引用。您需要将签名更改为;

iterator(const iterator& other) 

Visual C++ 允许它,但默认情况下会发出 "nonstandard extension used" 警告。

我建议阅读 Herb Sutter's post 以获得更详细的解释。