如何编译?

时间:2010-03-16 21:09:41

标签: c++

我有这个代码可以按预期编译和工作:

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;
}

但是现在,这个令我感到惊讶,我认为模板会自行解决,因为我已经将= operator()提供给了Left类。

int main()
{
  ...

  std::list<Right> rightLst;
  std::list<Left>  leftLst;

  // Assign a list of objects -- this doesn't compile
  leftLst = rightLst;
}

我可以执行哪些操作以便将rightLst转换为leftLst转换为一行?

另外,如果在Left上使用显式关键字怎么办?那么所提出的解决方案都不会起作用,即如果将Left定义为:

class Left
{
public:
  Left()
  {}
  explicit Left(Right const& right_)
  {
    .. // Do something ..
  }
  Left& operator = (Right const& right_)
  {
    // .. Do something ..
    return *this;
  }
};

请参阅,我正在努力避免在下面编写此代码以实现我想要做的事情:

  for(std::list<Right>::iterator it  = rightLst.begin();
                                 it != rightLst.end();
                                 it++ )
  {
    leftLst.push_back(Left(*it));
  }

我可以重新使用STL的哪些代码来替换上面的内容?

3 个答案:

答案 0 :(得分:8)

使用:

 std::copy(rightLst.begin(), rightLst.end(), std::back_inserter(leftLst));

这会将新元素添加到与leftLst中的元素对应的rightLst末尾。您需要向Left添加const Right &的构造函数。

如果leftLst和rightLst已经包含相同数量的元素,并且您想要覆盖leftLst中的元素,请使用:

std::copy(rightLst.begin(), rightLst.end(), leftLst.begin());

修改

更简单的是使用:

leftLst.assign(rightLst.begin(), rightLst.end());

这将替换leftLst中的所有元素(如果有的话),因此它将涵盖上面给出的两种情况。

普通赋值运算符在此处不起作用的原因是标准将其定义为仅接受相同类型的列表,因此不允许从list<Right>分配到list<Left>


如果构造函数声明为显式,则assign函数无法知道如何将Right转换为Left,因此无效。另一种选择是在Right上定义转换运算符:

Right::operator Left() { return Left();}

如果您不这样做,assign将无法编译。

上面给出的copy的第二个版本可以在没有转换运算符或转换构造函数的情况下工作(只需要一个赋值运算符),但它要求目标列表具有足够的元素。

答案 1 :(得分:7)

当您尝试分配时:

std::list<Right> rightLst;
std::list<Left>  leftLst;

leftList = rightList;

然后使用std :: list的operator =(),而不是包含类型的operator =()。但是列表的类型不同,因此无法分配。

答案 2 :(得分:1)

如果您将复制构造函数添加到Left

,该怎么办?
class Left
{
public:
  Left(Right const&)
  { // .. do something similar to operator =
  }
  Left& operator = (Right const&)
  //...

编辑:好的,因为复制构造函数没有修复它,所以你不能只使用=列表到列表的赋值。

尝试:

Left left(right.begin(), right.end());

或:

left.assign(right.begin(), right.end());

P.S。无论哪种方式,您仍然需要一个带有const Right&的复制构造函数。