我有一个家庭作业来做一个Matrix的模板类,其中包括一些非常基本和简单的东西。我们还需要为它创建一个前向迭代器类(一个嵌套的),它以标准方式运行,它应该专门支持一个复制构造函数。
这是相关的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等。它们初始化私有成员而不是其他任何东西。迭代器类也会重载++运算符
我面临的问题是使用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
如果我注释掉迭代器类的复制构造函数,那么代码在Linux(和windows)上编译得很好。如果我保留两个构造函数,那么g ++会抛出错误。它仿佛复制构造函数覆盖了前一个构造函数,我不明白为什么。
任何人都可以分享一下为何会发生这种情况吗?也许我该如何解决它?
答案 0 :(得分:4)
复制构造函数中的const
很重要,因为只有lvalues可以绑定到非const引用,但临时对象是rvalue,它们不能绑定到非const引用。您需要将签名更改为;
iterator(const iterator& other)
Visual C ++确实允许它,但会发出一个&#34;非标准扩展使用&#34;默认警告。
我建议您阅读Herb Sutter's post以获取更详细的解释。
答案 1 :(得分:1)
您只能传递临时值const&
(或按值)。 Visual Studio在这一点上是错误的。复制构造函数的正确签名是:
iterator(const iterator& other)