2010-03-16 46 views
3

我有这样的代码,编译和按预期工作:如何获得这个编译?

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

我能做些什么,这样我可以转换rightLstleftLst转换在单行?

另外,如果在左侧使用显式关键字会怎么样?然后没有提出的解决方案将工作,也就是说,如果左定义为:

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的哪些代码替换上述内容?

回答

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的第二个版本无需转换运算符或转换构造函数(仅需要赋值运算符),但它需要目标列表具有足够的元素。

+0

@interjay - 你能解释一下上面的代码不起作用吗? (这是OP的实际问题)。另外,对于STL新手来说,为什么你的解决方案应该被实际使用。谢谢! – DVK

+0

如果将Left拷贝构造函数声明为explicit,该怎么办? – sivabudh

+0

这两个列表是不同类型的[列表和列表],并且没有赋值运算符来连接这两个列表。 –

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()); 

附:无论哪种方式,你仍然需要一个复制构造函数,它需要一个const Right&

+0

我试过了,仍然得到相同的编译器错误。 – sivabudh

7

当您尝试分配:

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

leftList = rightList; 

随后的std ::列表,而不是所包含的类型的运算符=(),则使用。但这些列表是不同类型的,因此不能分配。

+0

operator =,不是运算符()。 – Paul

+0

@Paul谢谢 - 修正。 – 2010-03-16 21:21:01