我有这个代码编译和按预期工作:
class Right
{};
class Left
{
public:
Left& operator = (Right const&)
{
//... Do something ...
return *this;
}
};
int main()
{
Right right;
Left left;
// Assign individual object -- this works
left = right;
}
Run Code Online (Sandbox Code Playgroud)
但是现在,这个令我惊讶的是,我认为模板会自行解决,因为我已经提供= operator()了Left课程.
int main()
{
...
std::list<Right> rightLst;
std::list<Left> leftLst;
// Assign a list of objects -- this doesn't compile
leftLst = rightLst;
}
Run Code Online (Sandbox Code Playgroud)
我能做些什么,这样我就可以转换rightLst到leftLst在单行转换?
另外,如果在Left上使用显式关键字怎么办?那么所提出的解决方案都不会起作用,即如果将Left定义为:
class Left
{
public:
Left()
{}
explicit Left(Right const& right_)
{
.. // Do something ..
}
Left& operator = (Right const& right_)
{
// .. Do something ..
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
看,我试图避免在下面编写这段代码来实现我想要做的事情:
for(std::list<Right>::iterator it = rightLst.begin();
it != rightLst.end();
it++ )
{
leftLst.push_back(Left(*it));
}
Run Code Online (Sandbox Code Playgroud)
我可以重新使用STL的哪些代码来替换上面的内容?
使用:
std::copy(rightLst.begin(), rightLst.end(), std::back_inserter(leftLst));
Run Code Online (Sandbox Code Playgroud)
这将在leftLst对应于元素的末尾添加新元素rightLst.您将需要添加一个构造函数,Left那需要const Right &.
如果leftLst和rightLst已包含相同数量的元素,并且您要覆盖其中的元素leftLst,请使用:
std::copy(rightLst.begin(), rightLst.end(), leftLst.begin());
Run Code Online (Sandbox Code Playgroud)
编辑:
更简单的是使用:
leftLst.assign(rightLst.begin(), rightLst.end());
Run Code Online (Sandbox Code Playgroud)
这将替换leftLst中的所有元素(如果有的话),因此它将涵盖上面给出的两种情况.
,正常赋值操作符不能在这里工作的原因是,该标准定义为只接受同一类型的列表,所以它不会允许来自指定list<Right>给list<Left>.
如果构造函数声明为显式,那么assign函数将无法知道如何转换Right为Left,因此它将无法工作.另一种选择是改为定义转换运算符Right:
Right::operator Left() { return Left();}
Run Code Online (Sandbox Code Playgroud)
如果你不这样做,assign将无法编译.
copy上面给出的第二个版本将在没有转换运算符或转换构造函数的情况下工作(只需要一个赋值运算符),但它要求目标列表具有足够的元素.
小智 7
当您尝试分配时:
std::list<Right> rightLst;
std::list<Left> leftLst;
leftList = rightList;
Run Code Online (Sandbox Code Playgroud)
然后使用std :: list的operator =(),而不是包含类型的operator =().但是列表的类型不同,因此无法分配.