模板嵌套 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 以获得更详细的解释。
我有一项家庭作业要做矩阵的模板 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 以获得更详细的解释。