重载运算符以合并矢量
Overloading operator to merge vectors
我想在一个以向量为成员变量的类中重载运算符+,以便实现两个不同对象的向量的合并。换句话说,我希望创建一个新的对象,它将一行中两个初始向量的向量元素都作为向量。我尝试了以下代码,在operator+中收到一个关于std::copy的错误。问题出在哪里?
class TestVector
{
std::vector<int> myVector;
public:
TestVector(){};
TestVector(std::vector<int>);
std::vector<int> getVector();
TestVector operator +(TestVector);
};
std::vector<int> TestVector::getVector()
{
return myVector;
}
TestVector TestVector::operator+(TestVector param)
{
std::vector<int> tempVector;
std::vector<int> paramVector = param.getVector();
std::copy(paramVector.begin(), paramVector.end(), tempVector);
std::copy(myVector.begin(), myVector.end(), tempVector.end());
TestVector TestVector1(tempVector);
return TestVector1;
}
此外,第二个copy语句通常对合并两个向量有效吗?
更新:我在执行时遇到一个错误,说迭代器不适用于此语句。怎么了
tempVector.insert(tempVector.end((,param.getVector((.begin((,aram.getVector.eend(((;
std::copy
的第三个参数必须是迭代器,而不是容器。你可以这样使用std::back_inserter
:
std::copy(paramVector.begin(), paramVector.end(), std::back_inserter(tempVector));
第二个副本将编译,因为std::end()
返回一个迭代器,但它将中断,因为迭代器只是指向向量的末尾。当std::copy
尝试分配给它时,它不会增长向量;它只会调用未定义的行为。std::back_inserter
再次解决了这个问题。
无论如何,您根本不需要std::copy
,因为std::vector
直接提供了必要的语义:
TestVector TestVector::operator+(const TestVector& v)
{
std::vector<int> t(myVector);
t.insert(t.end(), v.myVector.begin(), v.myVector.end());
return TestVector(t);
}
请记住使用const &…
以避免过多的复制。例如,第二个构造函数不必要地复制输入向量,getVector()
不必要地拷贝内部向量。
即使是上面的解决方案也至少复制一次临时向量,这可以通过专门构建的构造函数来避免:
class TestVector
{
std::vector<int> myVector;
public:
TestVector() { }
TestVector(const std::vector<int>& v) : myVector(v) { }
const std::vector<int>& getVector() const { return myVector; }
TestVector operator+(const TestVector& v) const {
return TestVector(op_add(), *this, v);
}
private:
struct op_add { };
TestVector(op_add, const TestVector& a, const TestVector& b) : myVector(a) {
myVector.insert(myVector.end(), b.myVector.begin(), b.myVector.end());
}
};
std::copy
的第三个参数应该是某种输出迭代器。使用最安全的方法是插入迭代器。#include <iterator>
之后,您应该能够执行以下操作:
std::copy(paramVector.begin(), paramVector.end(), std::back_inserter(tempVector));
std::copy(myVector.begin(), myVector.end(), std::back_inserter(tempVector));
std::back_inserter
是为给定容器创建适当back_insert_iterator
的辅助函数模板。
还要注意,你正在制作大量的副本。就我个人而言,我会将operator+
作为一个自由函数,并通过const引用获取参数。目前,operator+
是非常量的,因此只能在非常量向量上调用,并通过复制获取其第二个参数。如果声明getVector
:const TestVector& getVector() const;
,那么您可以执行类似的操作。
TestVector operator+(const TestVector& lhs, const TestVector& rhs)
{
std::vector<int> ret( lhs.getVector() );
ret.insert( ret.end(), rhs.getVector().begin(), rhs.getVector().end() );
return TempVector(ret);
}
如果要为您的类型实现operator+
,我建议您还将operator+=
作为成员函数实现,然后根据前面的运算符实现operator+
:
// As a public member function
TestVector& TestVector::operator+=( const TestVector& rhs ) {
myVector.insert( myVector.end(), rhs.myVector.begin(), rhs.myVector.end();
return *this;
}
TestVector operator+( TestVector lhs, const TestVector& rhs ) {
lhs += rhs;
return lhs;
}
其优点是,您只需要再多几行代码,就可以免费获得一个新操作,它不需要友谊或为类型的内部细节提供访问器,并且对于用户代码不需要维护左手边运算符的情况,它是高效的(不需要复制(。同时CCD_ 21的实现可以作为一个自由函数(关于类型的对称性,即转换1(和有效的(在C++11编译器中,如果TestVector
有一个移动构造函数,那么它只会复制每个元素一次,因为唯一的成员是一个可移动的向量;在C++03中,return语句中有一个额外的副本,可以通过deafult构造和交换来删除(。
1注意:您可能需要考虑使TestVector( std::vector<int> const & )
显式,以避免隐式转换为TestVector
。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 使用C++程序合并排序没有得到正确的输出
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 使用运算符+将两个已排序的链表合并到位
- 如何使用重载运算符合并两个数组
- C++ - 使用取消引用运算符重载实现图形节点的合并
- 合并C++中的集合,也会重载运算符
- 重载运算符以合并矢量
- 使用位运算符将少量int型合并为unsigned long long(64位)
- 静态类型语言中的合并运算符
- 使用 OR 运算符将多个 for 循环合并为一个
- 用于合并数组的重载运算符+失败